看起来EasyMock 3.2版现在支持使用注释来设置模拟对象。我是EasyMock(以及Java)的新手,我正在尝试了解如何使用它。这些注释是做新事物还是只提供另一种做事方式? documentation说:
从EasyMock 3.2开始,现在可以使用注释创建模拟。这很好 以及创建模拟并将其注入测试类的更短方法。 以下是上面的示例,现在使用注释:...
然后有一个列表显示@TestSubject和@Mock注释的使用,但我不明白它是如何工作的。似乎它将被测试类的私有字段神奇地设置为模拟对象。在我的大多数情况下,我只想制作返回预定义值的模拟对象,以便在JUnit测试用例中使用(目前不关心验证调用哪些,调用它们的次数等)。例如,对于某些测试,我想创建一个假的HttpServletRequest
对象,如下所示:
public class SomeTest {
// Construct mock object for typical HTTP request for the URL below
private static final String REQUEST_URL = "http://www.example.com/path/to/file?query=1&b=2#some-fragment";
private static final Map<String, String> requestHeaderMap;
static {
Map<String, String> requestHeaders = new LinkedHashMap<String, String>();
requestHeaders.put("host", "www.example.com");
// ... (add any other desired headers here) ...
requestHeaderMap = Collections.unmodifiableMap(requestHeaders);
}
private HttpServletRequest httpServletRequest;
// ...
@Before
public void setUp() throws Exception {
httpServletRequest = createNiceMock(HttpServletRequest.class);
expect(httpServletRequest.getRequestURI()).andReturn(REQUEST_URL).anyTimes();
expect(httpServletRequest.getHeaderNames()).andReturn(Collections.enumeration(requestHeaderMap.keySet())).anyTimes();
capturedString = new Capture<String>();
expect(httpServletRequest.getHeader(capture(capturedString))).andAnswer(new IAnswer<String>() {
public String answer() throws Throwable {
String headerName = capturedString.getValue().toLowerCase();
if (requestHeaderMap.containsKey(headerName))
return requestHeaderMap.get(headerName);
else
return "";
}
}).anyTimes();
replay(httpServletRequest);
// ...
}
@Test
public void someMethod_givenAnHttpServletRequest_shouldDoSomething() {
// ...
}
}
我可以更改上面的代码来使用注释吗?如果是的话,我应该吗?在什么情况下?
我认为将@Mock注释放在实例变量声明之上会自动处理createNiceMock(...)
部分,但这似乎不起作用,所以我怀疑我误解了一些东西。
答案 0 :(得分:2)
检查他们的源代码,他们使用反射将任何带有@Mock的内容注入到@TestSubject的字段中。他们的方法的javadoc
public static void injectMocks(final Object obj)
EasyMockSupport.java中的说:
将模拟注入到参数中传递的类中使用{@link Mock}注释的每个字段。然后,将这些模拟注入到使用TestSubject注释的每个类的字段中。
规则是
- 忽略静态和最终字段
- 如果可以将模拟分配给字段,请执行此操作。同一个模拟被分配不止一次
- 如果没有可以为某个字段分配模拟,请以静默方式跳过
- 如果可以为同一字段分配两个模拟,则返回错误
- 在超类
上递归搜索字段注意:如果参数扩展了EasyMockSupport,将使用它创建模拟以允许replayAll / verifyAll随后工作
@param obj注入模拟的对象
@since 3.2
public static void injectMocks(final Object obj){ ... }
为了使用@Mock注释,你需要一个@TestSubject,它有一个HttpServletRequest字段,供EasyMock设置@Mock on(通过反射)。提供注释是为了使测试更容易,它让你跳过createMock,然后自己调用定居者。