我在服务类中有一个方法可以调用外部api。我将如何模拟此okHttpClient调用?我已经尝试过用模仿工具来做到这一点,但是这样做没有运气。
//this is the format of the method that i want to test
public string sendMess(EventObj event) {
OkHttpClient client = new OkHttpClient();
//build payload using the information stored in the payload object
ResponseBody body =
RequestBody.create(MediaType.parse("application/json"), payload);
Request request = //built using the Requestbody
//trying to mock a response from execute
Response response = client.newCall(request).execute();
//other logic
}
如果可以帮助测试,我愿意重构服务类。任何建议和建议表示赞赏。谢谢。
答案 0 :(得分:1)
由于您使用的是spring-boot
,因此请继续管理bean。
1)首先创建OkHttpClient
作为spring bean,以便您可以在整个应用程序中使用它
@Configuration
public class Config {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient();
}
}
2)然后在服务类@Autowire
OkHttpClient
中使用它
@Service
public class SendMsgService {
@Autowired
private OkHttpClient okHttpClient;
public string sendMess(EventObj event) {
ResponseBody body = RequestBody.create(MediaType.parse("application/json"), payload);
Request request = //built using the Requestbody
//trying to mock a response from execute
Response response = okHttpClient.newCall(request).execute();
//other logic
}
}
测试
3)现在在Test类中使用@SpringBootTest
,@RunWith(SpringRunner.class)
和@MockBean
当我们需要引导整个容器时,可以使用@SpringBootTest批注。注释通过创建将在我们的测试中使用的ApplicationContext起作用。
@RunWith(SpringRunner.class)用于在Spring Boot测试功能和JUnit之间建立桥梁。每当我们在JUnit测试中使用任何Spring Boot测试功能时,都将需要此批注。
@MockBean注释,可用于向Spring ApplicationContext添加模拟。
@SpringBootTest
@RunWith(SpringRunner.class)
public class ServiceTest {
@Autowire
private SendMsgService sendMsgService;
@MockBean
private OkHttpClient okHttpClient;
@Test
public void testSendMsg(){
given(this.okHttpClient.newCall(ArgumentMatchers.any())
.execute()).willReturn(String);
EventObj event = //event object
String result = sendMsgService.sendMess(event);
}
}
答案 1 :(得分:0)
我建议您在OkHttpClient
类中将Configuration
的实例化到自己的方法中。之后,您可以@Inject
在需要的任何地方使用客户端,并且测试变得更加容易,因为您可以@Mock
离开它。
可以说是Spring
管理的bean:
@Configuration
public class OkHttpClientConfiguration {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient();
}
}
…您的生产班级:
@Component
public class ProductionClass {
@Inject
private OkHttpClient okHttpClient;
public string sendMess(EventObj event) {
okHttpClient // whatever you want
[…]
}
}
...以及您的测试:
public class SpyTest {
@InjectMocks
private ProductionClass productionClass;
@Mock
private OkHttpClient okHttpClient;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void spyInsteadOfPowermock() {
Request request = // mock the request
when(okHttpClient.newCall(request)).thenReturn(mock(Call.class));
}
}