我使用泽西岛开发了休息服务。现在我想为这个Web服务编写一些集成测试,但由于并非所有从Web服务中使用的类都已经实现,我需要模拟它们中的一些。例如,我有以下类:
public class A {
private String getWeather() {
return null;
}
}
我的网络服务如下:
@Path("/myresource")
public class MyResource {
@GET
@Produces("text/plain")
public String getIt() {
A a = new A();
return a.getWeather();
}
}
问题是getWeather函数没有准备好所以我需要模拟这个函数的返回值。但对于我发出休息呼叫的集成测试,我不知道该怎么做。
有什么想法吗?
答案 0 :(得分:3)
要使您的设计与A分离,您应该将其作为参数传递给MyResource。然后你可以轻松地用手或模拟它来模拟它。使用构造函数注入时,它看起来像这样:
@Path("/myresource")
public class MyResource {
private A a;
public MyResource(A a) {
this.a = a;
}
@GET
@Produces("text/plain")
public String getIt() {
return a.getWeather();
}
}
您可以使用
进行测试@Test
public void shouldGetIt() {
A a = mock(A.class);
when(a.getWeather()).thenReturn("sunny!");
MyResource r = new MyResource(a);
assertThat(r.getIt(), is("sunny!));
}
这使您的设计脱钩。 MyResource不再直接依赖于A,而是依赖于任何看起来像A的东西。另一个好处是mockito不会弄乱你的类文件。这是您的代码经过测试 - 而不是即时生成的代码。
许多人认为建设者注射有点旧学校。我老了所以我喜欢它....随着春天(我不建议你选择一个框架),你可以像这样自动装配变量:
@Autowire
private A a;
你根本不需要构造函数。 Spring将找到A的唯一实现并将其插入此变量中。我更喜欢显式编程,所以我会在任何一天选择构造函数注入。
答案 1 :(得分:2)
您可以使用Power Mockito
(https://code.google.com/p/powermock/wiki/MockitoUsage)
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyResource.class })
public class MyResourceTest {
@Test
public void testGetIt()() {
MyResource mr = new MyResource();
//Setup mock
A mockA = PowerMockito.mock(A.class);
String mockReturn = "Some String";
//Stub new A() with your mock
PowerMockito.whenNew(A.class).withAnyArguments().thenReturn(mockA);
PowerMockito.doReturn(mockReturn).when(mockA).getWeather();
String ret = mr.getIt();
//asserts go here
}
}
请注意,您可以使用PowerMockito的whenNew
模拟本地变量创建 - 这应该照顾您对A a = new A()
方法中getIt()
代码的关注。