【问题标题】:How to Mock repository calls ATG如何模拟存储库调用 ATG
【发布时间】:2013-08-01 06:59:10
【问题描述】:

我们可以使用 Mockito 为实现存储库调用的方法编写测试吗?例如下面的方法是使用命名查询从图书存储库中获取电子书 -

public RepositoryItem[] getEBooks(DynamoHttpServletRequest request) {
    RepositoryItem[] results = null;
    Repository rep = (Repository) request.resolveName("/atg/products/BookRepository");
    try {
        RepositoryItemDescriptor desc = rep.getItemDescriptor("Book");
        RepositoryView view = desc.getRepositoryView();
        if (view instanceof NamedQueryView) {
            NamedQueryView nameView = (NamedQueryView) view;
            ParameterSupportView pSupportView = (ParameterSupportView) view;
            String queryName = "GetBooks";
            Query namedQuery = nameView.getNamedQuery(queryName);
            Object[] params = { "ebook" }; //book type
            results = pSupportView.executeQuery(namedQuery, params);
        }
    } catch (RepositoryException e) {
        logError(e.getMessage());
    }
    return results;
}

谢谢。

【问题讨论】:

    标签: mockito atg


    【解决方案1】:

    是的,你可以。问题是您是否在这种情况下测试您的代码或 ATG?

    假设您的上述方法包含在名为 GetBooks 的类中,您的测试可能如下所示:

    @InjectMocks  private GetBooks testObj;
    
    @Mock private DynamoHttpServletRequest requestMock;
    @Mock private Repository bookRepositoryMock;
    @Mock private RepositoryItemDescriptor bookRepositoryItemDescriptorMock;
    @Mock private GSAView bookRepositoryViewMock; //The only oddity here but GSAView is the common denominator for NamedQueryView and ParameterSupportView 
    @Mock private Query namedQueryMock; 
    
    @Mock private RepositoryItem resultRepositoryItem1, resultRepositoryItem2;
    
    
    @BeforeMethod(groups = { "unit" })
    public void setup() throws Exception {
        testObj = new GetBooks();
        MockitoAnnotations.initMocks(this); 
    
        Mockito.when(requestMock.resolveName("/atg/products/BookRepository")).thenReturn(bookRepositoryMock);
        Mockito.when(bookRepositoryMock.getItemDescriptor("Book")).thenReturn(bookRepositoryItemDescriptorMock);
        Mockito.when(bookRepositoryItemDescriptorMock.getRepositoryView()).thenReturn(bookRepositoryViewMock);
        Mockito.when(bookRepositoryViewMock.getNamedQuery("GetBooks")).thenReturn(namedQueryMock);
    
        List<RepositoryItem> resultArrayList = new ArrayList<RepositoryItem>();
        resultArrayList.add(resultRepositoryItem1);
        resultArrayList.add(resultRepositoryItem2);
    
        Object[] params = { "ebook" }; //It may be simpler to test if this was a constant
    
        Mockito.when(bookRepositoryViewMock.executeQuery(namedQueryMock, params)).thenReturn(resultArrayList.toArray(new RepositoryItem[resultArrayList.size()]));
    
    }
    
    @Test(groups = { "unit" })
    public void testGetEBooks()throws Exception{ 
    
        RepositoryItem[] result = testObj.getEBooks(requestMock);
        Assert.assertTrue(result.length == 2); //What do you want to test?
    }
    

    当通过TestNG 执行时,这会给出greenbar。但是你在这里真正测试的是什么?

    在单独的说明中。您应该更多地使用 (protected) 常量,因为这样您就可以在 Mockito 测试的包范围内使用它们。

    【讨论】:

    • 谢谢。那么目的是测试不是ATG的方法。通常,具有存储库调用的方法采用一些参数,使用该参数执行查询并返回结果。问题是,假设 ATG 将正确发挥其作用,我们能否避免为这种方法编写测试。或者,我们应该编写一个您在上面解释的最小方法。
    • @Saurabh 在我参与的一个项目中,我们为 droplets 和 formhandlers 编写了数百个测试,在大多数情况下,这涉及从存储库中获取数据。我们的测试主要集中在我们如何处理存储库中的数据,而不是(如上所述)我们如何获取数据。不幸的是,有时您必须模拟如何获取数据以测试数据的使用,因此这一切都取决于。上述方法对我来说效果很好,我也将它应用到我当前的项目中。
    • 谢谢。这些笔记将指导我在我的项目中编写测试。 :)
    • 正如您所说的表单处理程序,我们通常测试什么?因为,表单处理程序的目的是获取表单输入,调用一些服务来执行逻辑,最后重定向到错误页面(如果有任何错误)或成功页面。而在ATG中我们一般调用checkFormRedirect(getSuccessUrl(), getErrorUrl(), request, response);
    • 这一切都取决于。你验证你的表单输入吗?您是在单独的类中还是在 FormHandler 中验证这一点?你测试验证吗?如果你的验证失败,你怎么知道你去了successUrl?你的handle方法有多少个条件?你测试了其中的几个?仅仅因为您最终获得成功或错误的 Url 并不意味着您应该这样做?在“干净”的实现中,您的 FormHandlers 中不会有太多逻辑,但即使在开箱即用的 FormHandlers 中,您也有多个成功路径,那么您如何知道您的最终页面是正确的?测试一下。
    猜你喜欢
    • 2013-08-11
    • 2012-04-04
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    相关资源
    最近更新 更多