模拟RxJava异步http调用
我在模拟RxJava函数时遇到了一些麻烦,该函数会进行一些HTTP调用。我正在使用JUnit和Mockito模拟RxJava异步http调用,java,junit,mockito,rx-java,Java,Junit,Mockito,Rx Java,我在模拟RxJava函数时遇到了一些麻烦,该函数会进行一些HTTP调用。我正在使用JUnit和Mockito //Customer.java extends ServiceManager public Observable<String> getCustomerDetails(String uuidData){ String api = "http://someapi.com/" + uuidData; return callHttps(api, getHeader(
//Customer.java extends ServiceManager
public Observable<String> getCustomerDetails(String uuidData){
String api = "http://someapi.com/" + uuidData;
return callHttps(api, getHeader(),
"",
HttpMethod.GET)
.doOnError(failure -> logger.error("Error was raised while calling Profile Save of ORCH API:"
+ failure.getMessage()))
.doOnNext(httpClientResponse -> {
logger.info("");
})
.concatMap(RxHelper::toObservable)
.reduce(Buffer.buffer(), Buffer::appendBuffer)
.map(buffer -> buffer.toString("UTF-8"))
.map(entries -> entries);
}
private MultiMap getProfileHeader(){
MultiMap headers = MultiMap.caseInsensitiveMultiMap();
headers.add("Accept","application/json");
return headers;
}
public class ServiceManager {
@Inject
@Named("httpsClient")
private HttpClient httpsClient;
private static final Logger logger = LoggerFactory.getLogger(ServiceManager.class);
public Observable<HttpClientResponse> callHttps(String url, MultiMap headers, String body, HttpMethod httpMethod) {
return Observable.create(subscriber -> {
HttpClientRequest httpClientRequest = httpsClient.requestAbs(httpMethod, url);
httpClientRequest.exceptionHandler(event -> {
logger.error("Exception was raised :" + event.getMessage());
});
httpClientRequest.headers().addAll(headers);
RxHelper
.toObservable(httpClientRequest)
.subscribe(subscriber);
httpClientRequest.end(body);
});
}
}
//Customer.java扩展了ServiceManager
公共可观察的getCustomerDetails(字符串uuidData){
字符串api=”http://someapi.com/“+uuidData;
返回callHttps(api,getHeader(),
"",
HttpMethod.GET)
.doError(失败->记录器.error(“调用ORCH API的配置文件保存时引发错误:”
+失败。getMessage()))
.doOnNext(httpClientResponse->{
logger.info(“”);
})
.concatMap(RxHelper::toObservable)
.reduce(Buffer.Buffer(),Buffer::appendBuffer)
.map(buffer->buffer.toString(“UTF-8”))
.map(条目->条目);
}
私有多映射getProfileHeader(){
MultiMap headers=MultiMap.caseinsensitivimultimap();
添加(“接受”、“应用程序/json”);
返回标题;
}
公共类服务管理器{
@注入
@命名(“httpsClient”)
私有HttpClient HttpScClient;
私有静态最终记录器Logger=LoggerFactory.getLogger(ServiceManager.class);
公共可观察调用HTTPS(字符串url、多映射头、字符串正文、HttpMethod HttpMethod){
返回可观察。创建(订户->{
HttpClientRequest HttpClientRequest=HttpScClient.requestAbs(httpMethod,url);
httpClientRequest.exceptionHandler(事件->{
logger.error(“引发异常:+event.getMessage());
});
httpClientRequest.headers().addAll(headers);
RxHelper
.toObservable(httpClientRequest)
.认购(认购人);
httpClientRequest.end(正文);
});
}
}
如何模拟
callHttps
函数,使其返回HttpClientRequest
模拟响应。我的另一种方法是使用WireMock,但我想通过模拟上述函数找到一种方法。假设Customer
不必是final,您可以使用。基本上,在这个模式中,您可以扩展被测试的类,以使用新的模拟功能覆盖方法。因此,您可以扩展Customer
并覆盖callHttps()
,这样它实际上除了记录调用它之外什么都不做,这样您就可以验证它是否确实被调用了
请注意,我并不主张您应该像这样测试代码。通常情况下,使用此模式表示。因此,如果可以的话,完全放弃继承权。也就是说,如果必须,请尝试使用类似于以下示例代码的代码:
public class CustomerTest {
@Mock
private Observable<HttpClientResponse> mockObservable;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void getCustomerDetailsCallsCallHttps() {
CustomerSelfShunt customerUnderTest = new CustomerSelfShunt();
// Call the getCustomerDetails method. Should call overridden version of
// callHttps() that sets callHttpsInvoked.
Observable<String> actualObservable = customerUnderTest.getCustomerDetails("foo");
assertEquals(this.mockObservable, actualObservable);
assertTrue(customerUnderTest.callHttpsInvoked);
}
private class CustomerSelfShunt extends Customer {
boolean callHttpsInvoked = false;
public Observable<HttpClientResponse> callHttps(String url, MultiMap headers, String body, HttpMethod httpMethod) {
// do nothing implementation, just record that this method was called.
callHttpsInvoked = true;
}
}
}
公共类客户测试{
@嘲弄
私人可观察的或可观察的;
@以前
公共作废设置(){
initMocks(this);
}
@试验
public void getCustomerDetailsCallsCallHttps(){
CustomerSelfShuttle customerUnderTest=新CustomerSelfShuttle();
//调用getCustomerDetails方法。应调用
//callHttps(),用于设置callHttpsInvoked。
Observable ActualObjectable=customerUnderTest.getCustomerDetails(“foo”);
assertEquals(this.mockObservable,actualObservable);
assertTrue(customerUnderTest.callHttpsInvoked);
}
私有类CustomerSelf扩展了Customer{
布尔callHttpSinvoke=false;
公共可观察调用HTTPS(字符串url、多映射头、字符串正文、HttpMethod HttpMethod){
//不执行任何实现,只记录调用了此方法。
callHttpsInvoked=true;
}
}
}
假设客户
不必是最终客户,您可以使用。基本上,在这个模式中,您可以扩展被测试的类,以使用新的模拟功能覆盖方法。因此,您可以扩展Customer
并覆盖callHttps()
,这样它实际上除了记录调用它之外什么都不做,这样您就可以验证它是否确实被调用了
请注意,我并不主张您应该像这样测试代码。通常情况下,使用此模式表示。因此,如果可以的话,完全放弃继承权。也就是说,如果必须,请尝试使用类似于以下示例代码的代码:
public class CustomerTest {
@Mock
private Observable<HttpClientResponse> mockObservable;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void getCustomerDetailsCallsCallHttps() {
CustomerSelfShunt customerUnderTest = new CustomerSelfShunt();
// Call the getCustomerDetails method. Should call overridden version of
// callHttps() that sets callHttpsInvoked.
Observable<String> actualObservable = customerUnderTest.getCustomerDetails("foo");
assertEquals(this.mockObservable, actualObservable);
assertTrue(customerUnderTest.callHttpsInvoked);
}
private class CustomerSelfShunt extends Customer {
boolean callHttpsInvoked = false;
public Observable<HttpClientResponse> callHttps(String url, MultiMap headers, String body, HttpMethod httpMethod) {
// do nothing implementation, just record that this method was called.
callHttpsInvoked = true;
}
}
}
公共类客户测试{
@嘲弄
私人可观察的或可观察的;
@以前
公共作废设置(){
initMocks(this);
}
@试验
public void getCustomerDetailsCallsCallHttps(){
CustomerSelfShuttle customerUnderTest=新CustomerSelfShuttle();
//调用getCustomerDetails方法。应调用
//callHttps(),用于设置callHttpsInvoked。
Observable ActualObjectable=customerUnderTest.getCustomerDetails(“foo”);
assertEquals(this.mockObservable,actualObservable);
assertTrue(customerUnderTest.callHttpsInvoked);
}
私有类CustomerSelf扩展了Customer{
布尔callHttpSinvoke=false;
公共可观察调用HTTPS(字符串url、多映射头、字符串正文、HttpMethod HttpMethod){
//不执行任何实现,只记录调用了此方法。
callHttpsInvoked=true;
}
}
}
一些选项:
package com.sbp;
导入静态org.junit.Assert.assertEquals;
导入静态org.mockito.Matchers.any;
导入静态org.mockito.Matchers.anyString;
导入静态org.mockito.mockito.mock;
导入静态org.mockito.mockito.when;
导入静态rx.Observable.just;
导入io.vertx.core.MultiMap;
导入io.vertx.core.http.HttpClientResponse;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.mockito.Spy;
导入org.mockito.runners.MockitoJUnitRunner;
英普