-1

Mockito作为一个概念,我是新手。你能帮我理解Mockito在 ATG 中使用表单处理程序吗?一些例子将不胜感激。

4

3 回答 3

0

其他类似问题有一个很好的答案(与 ATG 相关):using-mockito-for-writing-atg-test-case。请查看它是否包含您需要的内容。

众所周知,许多 ATG 特定组件(尤其是表单处理程序)“可测试性较低”(与使用 TDD/BDD 方法开发的组件相比),OOTB 组件(包括参考应用程序)的 b/c 设计并不总是遵守遵循“低耦合、高内聚”的原则

但是通用方法仍然适用于为所有 ATG 组件编写单元测试。

于 2013-11-03T18:51:58.387 回答
0

这是我对表单处理程序进行单元测试时所做的事情(至少在我设法发布 AtgDust 的主要更新之前)。请注意,我不使用通配符导入,所以我不确定这是否会导致任何命名空间冲突。

import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.*;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import atg.servlet.*;
import some.form.handler.FormHandler;

@RunWith(JUnit4.class)
public class FormHandlerTest {
  @Mock DynamoHttpServletRequest request;
  @Mock DynamoHttpServletResponse response;
  FormHandler handler;

  @Before
  public void setup() {
    initMocks(this);
    handler = new FormHandler();
  }

  @Test
  public void testSubmitHandlerRedirects() {
    handler.handleSubmit(request, response);
    verify(response).sendLocalRedirect(eq("/success.jsp"), eq(request));
    assertThat(handler.getFormError(), is(false));
  }
}

基本思想是在模拟对象方法调用上使用 when() 为模拟/存根设置自定义行为,以返回一些测试值或抛出异常,然后 verify() 模拟对象被调用了准确的次数(默认情况下) case, once),并对表单处理程序中已更改的数据执行任何断言。本质上,您将希望使用 when() 来模拟需要返回其他模拟对象的任何类型的方法调用。你什么时候需要这样做?最简单的判断方法是当您由于使用空值、零、空字符串等而出现 NPE 或其他运行时异常时。

在集成测试中,理想情况下,您将能够使用一种介于两者之间的模拟/测试 servlet,它假装像一个完整的应用程序服务器一样工作,执行最小的请求/会话/全局范围管理。据我所知,这对 Arquillian 来说是一个很好的用途,但我还没有开始尝试。

于 2013-12-14T23:43:21.930 回答
0

下面是我们使用 Mockito 测试 ATG FormHandlers 的框架。显然,您需要进行所有适当的测试,但这应该可以帮助您入门。

    public class AcmeFormHandlerTest {

        @Spy @InjectMocks private AcmeFormHandler testObj;
        @Mock private Validator<AcmeInterface> acmeValidatorMock;

        @Mock private DynamoHttpServletRequest requestMock;
        @Mock private DynamoHttpServletResponse responseMock;

        private static final String ERROR1_KEY = "error1";
        private static final String ERROR1_VALUE = "error1value";

        @BeforeMethod(groups = { "unit" })
        public void setUp() throws Exception {
            testObj = new AcmeFormHandler();
            initMocks(this);
        }

        //Test the happy path scenario
        @Test(groups = { "unit" })
        public void testWithValidData() throws Exception {
            testObj.handleUpdate(requestMock, responseMock);
            //Assume your formhandler calls a helper method, then ensure the helper method is called once. You verify the working of your helper method as you would do any Unit test
            Mockito.verify(testObj).update(Matchers.refEq(requestMock), Matchers.refEq(responseMock), Mockito.anyString(), (AcmeBean) Mockito.anyObject());
        }

        //Test a validation exception
        @Test(groups = { "unit" })
        public void testWithInvalidData() throws Exception {
            Map<String, String> validationMessages = new HashMap<String, String>();
            validationMessages.put(ERROR1_KEY, ERROR1_VALUE);
            when(acmeValidatorMock.validate((AcmeInterface) Mockito.any())).thenReturn(validationMessages);

            testObj.handleUpdate(requestMock, responseMock);

            assertEquals(1, testObj.getFormExceptions().size());
            DropletFormException exception = (DropletFormException) testObj.getFormExceptions().get(0);
            Assert.assertEquals(exception.getMessage(), ERROR1_VALUE);
        }

        //Test a runtime exception
        @Test(groups = { "unit" })
        public void testWithRunProcessException() throws Exception {
            doThrow(new RunProcessException("")).when(testObj).update(Matchers.refEq(requestMock), Matchers.refEq(responseMock), Mockito.anyString(), (AcmeBean) Mockito.anyObject());

            testObj.handleAddGiftCardToCart(requestMock, responseMock);

            assertEquals(1, testObj.getFormExceptions().size());
            DropletFormException exception = (DropletFormException) testObj.getFormExceptions().get(0);
            Assert.assertEquals(exception.getMessage(), GENERAL_ERROR_KEY);
        }

    }

显然,上面只是一个框架,非常适合我们开发 FormHandlers 的方式。如果您选择,您还可以为重定向和类似的东西添加验证:

Mockito.verify(responseMock, Mockito.times(1)).sendLocalRedirect(SUCCESS_URL, requestMock);

最终,测试其他人代码的警告仍然适用。

于 2013-11-05T11:13:36.793 回答