看起来 EasyMock 3.2 版本现在支持使用注释来设置模拟对象。我是 EasyMock(以及一般的 Java)新手,我正在尝试了解如何使用它。这些注释是否做了一些新的事情,或者只是提供了一种替代方法? documentation说:
Since EasyMock 3.2, it is now possible to create mocks using annotations. This is a nice and shorter way to create your mocks and inject them to the tested class. Here is the example above, now using annotations: ...
然后有一个列表显示了 @TestSubject 和 @Mock 注释的使用,但我不明白它是如何工作的。看起来好像它神奇地将被测类的私有(private)字段设置为模拟对象。在大多数情况下,我只想制作返回预定义值的模拟对象,以便在 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(...)
部分,但这似乎不起作用,所以我怀疑我我误解了一些东西。
最佳答案
检查他们的源代码,他们使用反射将带有 @Mock 的任何内容注入(inject)到 @TestSubject 的字段中。他们的方法的 javadoc
public static void injectMocks(final Object obj)
在 EasyMockSupport.java 中说:
Inject a mock to every fields annotated with {@link Mock} on the class passed in parameter. Then, inject these mocks to the fields of every class annotated with TestSubject.
The rules are
- Static and final fields are ignored
- If a mock can be assigned to a field, do it. The same mock an be assigned more than once
- If no mock can be assigned to a field, skip it silently
- If two mocks can be assigned to the same field, return an error
- Fields are searched recursively on the superclasses
Note: If the parameter extends EasyMockSupport, the mocks will be created using it to allow replayAll/verifyAll to work afterwards
@param obj the object on which to inject mocks
@since 3.2
public static void injectMocks(final Object obj) { ... }
为了使用 @Mock 注释,您需要一个 @TestSubject,它具有一个 HttpServletRequest 字段,以便 EasyMock 设置 @Mock(通过反射)。提供注释是为了让连接测试变得更容易,它让您可以跳过 createMock,然后自己调用 setter。
关于java - 我该如何使用 EasyMock 的 @Mock 注解(3.2 版本新增)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18195820/