我正在尝试测试我的春季休息客户端,但我遇到了麻烦。这是我的客户班:
@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
和hasError
ResponseErrorHandler
类方法的类。
现在我的测试课为
@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
该问题是因为当您正常运行应用程序时,Spring Boot自动为您配置RestTemplateBuilder
(由于@SpringBootApplication
注释),但是在测试中,您没有相应的@SpringBootTest
注释,并且Myclient构造函数中的restTemplateBuilder
当然是null(在此尝试调用build()方法时会产生您的错误)。
如果您按原样添加它,它将使用应用程序默认配置上下文,并且RestTemplateBuilder
和MyResponseErrorHandler
都可以正常工作(请注意,在这种情况下,MyClient
和MyResponseErrorHandler
都应将其配置为bean -F.E. -F.E.使用@Component
)。
@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...
}
}
另外,不要对RestTemplate
做任何事情,因为它将在myclient构造函数中以编程方式创建。
另一种方法是创建单独的测试配置,您可以在其中获取默认的RestTemplateBuilder
BEAN(由Spring提供)和嘲笑的MyResponseErrorHandler
(以后以稍后配置其行为)。它可以使您完全控制如何在不使用应用程序上下文的情况下配置所有豆子进行测试。
如果您想深入研究 - 以下是实现此目的的步骤:
- 使用
MyResponseErrorHandler
BEAN创建测试配置类:
@TestConfiguration
public class MyClientTestConfiguration {
@Autowired
private RestTemplateBuilder restTemplateBuilder;
@Bean
public ResponseErrorHandler myResponseErrorHandler() {
return Mockito.mock(MyResponseErrorHandler.class);
}
@Bean
public MyClient myClient() {
return new MyClient(restTemplateBuilder, myResponseErrorHandler());
}
}
- 您的测试课将是这样:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyClientTestConfiguration.class)
public class MyClientTest {
@Autowired //wired from MyClientTestConfiguration class
private MyClient myClient;
@Autowired //wired from MyClientTestConfiguration class
private MyResponseErrorHandler myResponseErrorHandler;
@Test
public void sampleTest() throws IOException {
//The example of configuring myResponseErrorHandler behavior
Mockito.when(myResponseErrorHandler.hasError(Mockito.any())).thenReturn(true);
//Calling myClient method...
//Asserts...
}
}
您有一个很好的示例,用于与依赖关系模拟自动服务,
在您的情况下,您还需要模拟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 );
}
@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
}
下面的示例是正常运行时。修改使用SpringRunner.class
。
公共类myclienttest {
private MyClient myClient;
@Mock private RestTemplate restTemplate;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
myClient = new MyClient(restTemplate);
}
//test cases here
}