okhttp3调用的测试方法

时间:2019-03-25 19:55:03

标签: java unit-testing spring-boot mocking okhttp3

我在服务类中有一个方法可以调用外部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
}

如果可以帮助测试,我愿意重构服务类。任何建议和建议表示赞赏。谢谢。

2 个答案:

答案 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));
    }
}