在春季模拟RestTemplate

时间:2019-02-25 22:40:43

标签: junit mockito resttemplate

我正在尝试测试我的春季休假客户,但遇到了麻烦。这是我的客户班:

@Component
public class MyClient{    

    private RestTemplate restTemplate;


    @Autowired
    public MyClient(RestTemplateBuilder restTemplateBuilder,ResponseErrorHandler myResponseErrorHandler) {
        this.restTemplate = restTemplateBuilder
                .errorHandler(myResponseErrorHandler)
                .build();
    }
    //other codes here
}

这里myResponseErrorHandler是覆盖handleError类的hasErrorResponseErrorHandler方法的类。

现在我的测试课程为

    @RunWith(SpringRunner.class)
    public class MyClientTest {    

        @InjectMocks
        MyClient myClient;
        @Mock
        RestTemplate restTemplate;
        @Mock
        RestTemplateBuilder restTemplateBuilder;

       //test cases here
    }

但是出现以下错误,我不确定如何解决此问题。

You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

3 个答案:

答案 0 :(得分:4)

该问题是因为当您正常运行应用程序时,Spring Boot会自动为您配置RestTemplateBuilder(因为有@SpringBootApplication注释),但是在测试中您没有相应的{{1} }注释,而MyClient的构造函数中的@SpringBootTest当然是null(尝试在其上调用build()方法时会产生错误)。

如果按原样添加它,它将使用应用程序默认配置上下文,并且restTemplateBuilderRestTemplateBuilder都将是工作Bean(请注意,在这种情况下,MyResponseErrorHandler和{ {1}}应该已经配置为bean-通过用MyClient标记它们来实现。)

MyResponseErrorHandler

此外,不要对@Component进行任何操作,因为它将在MyClient构造函数中以编程方式创建。

另一种方法是创建单独的测试配置,您可以在其中获取默认的@RunWith(SpringRunner.class) @SpringBootTest public class MyClientTest { @Autowired private MyClient myClient; @Mock private MyResponseErrorHandler myResponseErrorHandler; @Test public void sampleTest() throws IOException { //The example of configuring myResponseErrorHandler behavior Mockito.when(myResponseErrorHandler.hasError(Mockito.any())).thenReturn(true); //Call myClient method //Asserts... } } bean(由Spring提供)和模拟的RestTemplate(用于稍后配置其行为) )。它可以让您完全控制如何配置所有bean进行测试而无需使用应用程序上下文。

如果您想深入了解它-以下是实现此目的的步骤:

  1. 使用RestTemplateBuilder bean创建测试配置类:
MyResponseErrorHandler
  1. 您的测试课程如下:
MyResponseErrorHandler

答案 1 :(得分:2)

您有一个不错的example,可以模拟具有依赖项的自动装配服务,

在您的情况下,您还需要模拟ResponseErrorHandler

@RunWith(MockitoJUnitRunner.class)
public class MyClientTest {

@Mock
private ResponseErrorHandler responseErrorHandler ;

@Mock
private RestTemplateBuilder restTemplateBuilder ;

private MyClient myClient;

@Before
void setUp() {
    myClient = new MyClient(restTemplateBuilder ,responseErrorHandler );
}

答案 2 :(得分:1)

<script type='text/javascript'>
    $(document).ready(function(){
        $("#myform").submit(function(e) {
            e.preventDefault();
            var parms = {
                position : $("#position").val(),
                location : $("#location").val()
            };
            var par_val;
            var param_id = new window.URLSearchParams(window.location.search);
            par_val = param_id.get('id');
            console.log(par_val);
            var par_url = par_val;

            $.ajax({
                url: "http://localhost:3000/joblists/"+id_val,
                method: 'POST', //or you can use GET
                dataType : "json", //REMOVED CONTENT TYPE AND ASYNC
                data: {send_obj:JSON.stringify(parms)},  //ADDED OBJECT FOR DATA
                success: function(data){
                    console.log('Submission was successful.');
                    console.log(data);
                },
                error: function (data) {
                    console.log('An error occurred.');
                    console.log(data);
                },   
            })
        });
    });
</script>

下面的示例是正常运行时的示例。修改以使用@Component public class MyClient{ private RestTemplate restTemplate; @Autowired public MyClient(RestTemplateBuilder restTemplateBuilder,ResponseErrorHandler myResponseErrorHandler) { this(restTemplateBuilder .errorHandler(myResponseErrorHandler) .build()); } MyClient(RestTemplate template) { this.restTemplate = template; } //other codes here }

公共类MyClientTest {

SpringRunner.class