java - 我该如何使用 EasyMock 的 @Mock 注解(3.2 版本新增)?

标签 java junit4 easymock

看起来 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/

相关文章:

java - Android Studio Soundboard 按钮在切换 Activity 后不会播放声音我只能按 7 次才停止

java - 如何编写返回类型为void的测试用例readFile方法

java - JUnit 多次运行测试

java - EasyMock 和返回泛型类的方法

java - 使用 PowerMock- EasyMock 时意外的方法调用

java - 为方法链配置checkstyle?

java - java中的中缀到后缀的转换

java - 多线程同时运行进程

java - 如何使用 JUnit 和 EasyMock 在 MVC 集成测试中模拟 View

java - 如何使用 ExecutorService 等待所有线程完成?