Тестовый метод с вызовом okhttp3 - PullRequest
1 голос
/ 25 марта 2019

У меня есть метод в классе обслуживания, который делает вызов к внешнему 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
}

Я открыт для рефакторинга класса обслуживания, если это поможет с тестированием.Любые предложения и рекомендации приветствуются.Спасибо.

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Поскольку вы используете spring-boot, оставьте управление бобами на весну.

1) Сначала создайте OkHttpClient как пружинный боб, чтобы вы могли использовать его во всем приложении

@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) Теперь в тестовых классах используются @SpringBootTest, @RunWith(SpringRunner.class) и @MockBean

Аннотация @SpringBootTest может использоваться, когда нам нужно загрузить весь контейнер. Аннотация работает путем создания ApplicationContext, который будет использоваться в наших тестах.

@ RunWith (SpringRunner.class) используется для обеспечения моста между функциями тестирования Spring Boot и JUnit. Всякий раз, когда мы используем какие-либо функции тестирования Spring Boot в наших тестах JUnit, эта аннотация потребуется.

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

  }
 }
0 голосов
/ 25 марта 2019

Я бы предложил, чтобы вы извлекли экземпляр вашего OkHttpClient к собственному методу в классе Configuration.После этого вы можете @Inject клиентить где угодно, и тестирование станет намного проще, потому что вы можете @Mock его убрать.

Так сказать, Spring -управляемый компонент:

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