1

看起来 EasyMock 3.2 版现在支持使用注释来设置模拟对象。我是 EasyMock(和一般 Java)的新手,我正在尝试了解如何使用它。这些注释是做一些新的事情还是只是提供另一种做事的方式?文档说:

从 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(...)部分,但这似乎不起作用,所以我怀疑我误解了一些东西。

4

1 回答 1

2

检查他们的源代码,他们正在使用反射将带有@Mock 的任何内容注入到@TestSubject 的字段中。他们的方法的javadoc

public static void injectMocks(final Object obj)

在 EasyMockSupport.java 中说:

向传入参数的类上用 {@link Mock} 注释的每个字段注入一个模拟。然后,将这些模拟注入到使用 TestSubject 注释的每个类的字段中。

规则是

  • 静态和最终字段被忽略
  • 如果可以将模拟分配给字段,请执行此操作。同一个 mock 被多次分配
  • 如果不能将 mock 分配给某个字段,则静默跳过它
  • 如果两个 mock 可以分配给同一个字段,则返回错误
  • 在超类上递归搜索字段

注意:如果参数扩展 EasyMockSupport,将使用它创建模拟以允许 replayAll/verifyAll 之后工作

@param obj 要在其上注入模拟的对象

@从 3.2 开始

公共静态无效injectMocks(最终对象obj){...}

要使用 @Mock 注释,您需要一个具有 HttpServletRequest 字段的 @TestSubject,以便 EasyMock 设置 @Mock(通过反射)。提供注释是为了更容易连接测试,它让您跳过 createMock,然后自己调用 settter。

于 2013-08-21T20:16:58.867 回答