调用okhttp3的测试方法

Test method with okhttp3 call

我在服务 class 中有一个调用外部 api 的方法。我将如何模拟这个 okHttpClient 调用?我曾尝试使用 mockito 这样做,但没有成功。

//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
}

我愿意重构服务 class 如果它有助于测试。任何建议和建议表示赞赏。谢谢

我建议您将 OkHttpClient 的实例化到 Configuration class 中的自己的方法中。之后,您可以 @Inject 客户端在任何需要的地方,测试变得更加容易,因为您可以 @Mock 它离开。

这样说 Spring-managed bean:

@Configuration
public class OkHttpClientConfiguration {
    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient();
    }
}

…你的作品class:

@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));
    }
}

因为您正在使用 spring-boot 将管理 bean 留给 spring。

1) 首先将 OkHttpClient 创建为 spring bean 以便您可以在整个应用程序中使用它

@Configuration
public class Config {

@Bean
public OkHttpClient okHttpClient() {
    return new OkHttpClient();
    }
 }

2) 然后在服务中class @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) 现在在测试中 classes 使用 @SpringBootTest@RunWith(SpringRunner.class)@MockBean

The @SpringBootTest annotation can be used when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests.

@RunWith(SpringRunner.class) is used to provide a bridge between Spring Boot test features and JUnit. Whenever we are using any Spring Boot testing features in out JUnit tests, this annotation will be required.

@MockBean Annotation that can be used to add mocks to a 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);

  }
 }