为什么 mockito 没有注入正确的响应?
Why isnt mockito injecting the right response?
我正在尝试以下列方式使用 mockito。
这是主要内容的一部分 class IClient
。
public LoginResponse doLogin() {
WebTarget target = buildTarget();
MultivaluedMap<String, Object> authHeaders = prepareHeaders();
Builder buildRequest = buildRequest(authHeaders,target);
Response loginRsp = buildRequest
.post(Entity.entity(" Valid JSON string",
MediaType.APPLICATION_JSON_TYPE));
if(loginRsp == null)
LOGGER.error("Response was null");// Response is always returned as null.
这是我的测试代码
@Test
public void testdoLoginPass(){
Response response = Response.ok().build();
WebTarget webTarget = inner.buildTarget();
Builder buildRequest = inner.buildRequest( getMockHeaders(),webTarget);
when(buildRequest.post(Entity.entity(anyString(),
MediaType.APPLICATION_JSON_TYPE))).thenReturn(response);
Assert.assertNotNull(inner.doLogin());
}
我似乎无法弄清楚为什么响应总是为空。任何想法将不胜感激。
inner
是一个匿名的内部 class 对象,为 buildTarget()
和 buildRequest()
提供相应的模拟值。我能够看到正确的模拟值是通过调试生成的。
这里是匿名内幕class
inner= new IClient(client, propConfig){
WebTarget buildTarget(){
WebTarget target= mock(WebTarget.class);
LOGGER.error("Returning mock");
return target;
}
Builder buildRequest(final MultivaluedMap<String, Object> Headers,WebTarget target){
Builder builder = mock(Builder.class);
LOGGER.error("Returning mock");
return builder;
}
};
编辑-- 根据使用相同实例的建议。
这里是折射版本。
@Test
public void testdoIusLoginPass(){
inner= new IClient(client, propConfig){
WebTarget buildIUSTarget(){
WebTarget target= mock(WebTarget.class);
LOGGER.error("Returning mock");
return target;
}
Builder buildRequest(final MultivaluedMap<String, Object> authHeaders,WebTarget target){
builder = mock(Builder.class);
LOGGER.error("HashCode for Builder from inner Relevant method "+ builder.hashCode());
LOGGER.error("Returning mock");
return builder;
}
};
Response response = Response.ok().build();
WebTarget target = innerIUS.buildIUSTarget();
builder = innerIUS.buildRequest( getMockHeaders(),target);
when(builder.post(Entity.entity(any(String.class),
MediaType.APPLICATION_JSON))).thenReturn(response)
Assert.assertNotNull(inner.doLogin());
}
在实际方法中
public LoginResponse doIusLogin() {
WebTarget target = buildIUSTarget();
MultivaluedMap<String, Object> authHeaders = prepareIUSHeaders();
builder = buildRequest(authHeaders,target);
LOGGER.error("HashCode for Builder from doLogin "+ builder.hashCode());//identical hash codes
Response loginRsp = builder
.post(Entity.entity("Valid JSON String",
MediaType.APPLICATION_JSON_TYPE));
if(loginRsp == null)
LOGGER.error("Response was null");// Still null.
响应仍然为空。想法?
您的 when
匹配器从未被使用过,这就是它 null
的原因。
Mockito 不做深度参数比较,所以它比较
Entity.entity(anyString(), MediaType.APPLICATION_JSON_TYPE)
和
Entity.entity(" Valid JSON string", MediaType.APPLICATION_JSON_TYPE)
使用 Entity.equals
但它们不匹配。您应该编写自定义匹配器或将前一个表达式替换为 any(Entity.class)
.
编辑:此外,您在测试代码中使用了 Builder
的不同实例并测试了 class。您应该引用相同的实例。注入到被测的class.
编辑 #2:每次调用 inner.buildRequest
时都在重新创建 Builder
。在你的测试代码和你测试的class代码中写入System.out.println(buildRequest.hashCode());
,你会看到它们是两个不同的实例。
抱歉,我无法为您提供解决问题所需的代码 - 至少我看不到有多少测试基础设施可以这样做。
但是我应该说没有任何DI测试是非常复杂的。我建议你集成一些框架(Guice 或 Spring)并开始使用它,否则你的测试过程可能很快就会变成一场噩梦。
您应该为被移动的对象定义行为。
例如:
when(mockedList.get(anyInt())).thenReturn("element");
http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html
您必须将存根与模拟对象放在一起。例如
final Response response = Response.ok().build();
IClient inner = new IClient(client, propConfig){
Builder buildRequest(MultivaluedMap<String, Object> Headers, WebTarget target){
Builder builder = mock(Builder.class);
when(builder.post(any(Entity.class)).thenReturn(response)
return builder;
}
};
assertNotNull(inner.doLogin());
但是有一个小问题 - 这个测试几乎没有测试任何东西。
我正在尝试以下列方式使用 mockito。
这是主要内容的一部分 class IClient
。
public LoginResponse doLogin() {
WebTarget target = buildTarget();
MultivaluedMap<String, Object> authHeaders = prepareHeaders();
Builder buildRequest = buildRequest(authHeaders,target);
Response loginRsp = buildRequest
.post(Entity.entity(" Valid JSON string",
MediaType.APPLICATION_JSON_TYPE));
if(loginRsp == null)
LOGGER.error("Response was null");// Response is always returned as null.
这是我的测试代码
@Test
public void testdoLoginPass(){
Response response = Response.ok().build();
WebTarget webTarget = inner.buildTarget();
Builder buildRequest = inner.buildRequest( getMockHeaders(),webTarget);
when(buildRequest.post(Entity.entity(anyString(),
MediaType.APPLICATION_JSON_TYPE))).thenReturn(response);
Assert.assertNotNull(inner.doLogin());
}
我似乎无法弄清楚为什么响应总是为空。任何想法将不胜感激。
inner
是一个匿名的内部 class 对象,为 buildTarget()
和 buildRequest()
提供相应的模拟值。我能够看到正确的模拟值是通过调试生成的。
这里是匿名内幕class
inner= new IClient(client, propConfig){
WebTarget buildTarget(){
WebTarget target= mock(WebTarget.class);
LOGGER.error("Returning mock");
return target;
}
Builder buildRequest(final MultivaluedMap<String, Object> Headers,WebTarget target){
Builder builder = mock(Builder.class);
LOGGER.error("Returning mock");
return builder;
}
};
编辑-- 根据使用相同实例的建议。
这里是折射版本。
@Test
public void testdoIusLoginPass(){
inner= new IClient(client, propConfig){
WebTarget buildIUSTarget(){
WebTarget target= mock(WebTarget.class);
LOGGER.error("Returning mock");
return target;
}
Builder buildRequest(final MultivaluedMap<String, Object> authHeaders,WebTarget target){
builder = mock(Builder.class);
LOGGER.error("HashCode for Builder from inner Relevant method "+ builder.hashCode());
LOGGER.error("Returning mock");
return builder;
}
};
Response response = Response.ok().build();
WebTarget target = innerIUS.buildIUSTarget();
builder = innerIUS.buildRequest( getMockHeaders(),target);
when(builder.post(Entity.entity(any(String.class),
MediaType.APPLICATION_JSON))).thenReturn(response)
Assert.assertNotNull(inner.doLogin());
}
在实际方法中
public LoginResponse doIusLogin() {
WebTarget target = buildIUSTarget();
MultivaluedMap<String, Object> authHeaders = prepareIUSHeaders();
builder = buildRequest(authHeaders,target);
LOGGER.error("HashCode for Builder from doLogin "+ builder.hashCode());//identical hash codes
Response loginRsp = builder
.post(Entity.entity("Valid JSON String",
MediaType.APPLICATION_JSON_TYPE));
if(loginRsp == null)
LOGGER.error("Response was null");// Still null.
响应仍然为空。想法?
您的 when
匹配器从未被使用过,这就是它 null
的原因。
Mockito 不做深度参数比较,所以它比较
Entity.entity(anyString(), MediaType.APPLICATION_JSON_TYPE)
和
Entity.entity(" Valid JSON string", MediaType.APPLICATION_JSON_TYPE)
使用 Entity.equals
但它们不匹配。您应该编写自定义匹配器或将前一个表达式替换为 any(Entity.class)
.
编辑:此外,您在测试代码中使用了 Builder
的不同实例并测试了 class。您应该引用相同的实例。注入到被测的class.
编辑 #2:每次调用 inner.buildRequest
时都在重新创建 Builder
。在你的测试代码和你测试的class代码中写入System.out.println(buildRequest.hashCode());
,你会看到它们是两个不同的实例。
抱歉,我无法为您提供解决问题所需的代码 - 至少我看不到有多少测试基础设施可以这样做。
但是我应该说没有任何DI测试是非常复杂的。我建议你集成一些框架(Guice 或 Spring)并开始使用它,否则你的测试过程可能很快就会变成一场噩梦。
您应该为被移动的对象定义行为。 例如:
when(mockedList.get(anyInt())).thenReturn("element");
http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html
您必须将存根与模拟对象放在一起。例如
final Response response = Response.ok().build();
IClient inner = new IClient(client, propConfig){
Builder buildRequest(MultivaluedMap<String, Object> Headers, WebTarget target){
Builder builder = mock(Builder.class);
when(builder.post(any(Entity.class)).thenReturn(response)
return builder;
}
};
assertNotNull(inner.doLogin());
但是有一个小问题 - 这个测试几乎没有测试任何东西。