使用Mockito编写ATG测试用例

时间:2013-07-08 09:54:28

标签: mockito atg

有没有人知道使用Mockito为ATG编写单元测试用例?我偶然发现了以下讨论 - Automated unit tests for ATG developmentUsing PowerMock to obtain the ATG Nucleus in testing results in NPE

但需要帮助设置Nucleus和其他依赖项(DAS,DPS,DSS等)以及使用Mockito进行Droplet的示例测试类。

我们正在使用ATG Dust,我们必须设置所有依赖项。我想知道我们是否可以完全用Mockito取代ATG Dust。以下是我们编写测试用例的示例 -

  1. 用于设置Nucleus的基类 -
  2. package com.ebiz.market.support;
    
    import java.io.File;
    import java.util.Arrays;
    import atg.nucleus.NucleusTestUtils;
    import atg.test.AtgDustCase;
    import atg.test.util.FileUtil;
    
    public class BaseTestCase extends AtgDustCase {
    public atg.nucleus.Nucleus mNucleus = null;
    private final String ATGHOME="C://ATG/ATG9.4//home";
    private final String ATGHOMEPROPERTY = "atg.dynamo.home";
    
    protected void setUp() throws Exception {
    super.setUp();
    String dynamoHome = System.getProperty(ATGHOMEPROPERTY);
    if(dynamoHome == null)
    System.setProperty(ATGHOMEPROPERTY, ATGHOME);
    File configpath = NucleusTestUtils.getConfigpath(this.getClass(), this.getClass().getName(), true);
    FileUtil.copyDirectory("src/test/resources/config/test/", configpath.getAbsolutePath(), Arrays.asList(new String [] {".svn"}));
    copyConfigurationFiles(new String[]{"config"}, configpath.getAbsolutePath(), ".svn");
    }
    
    public File getConfigPath() {
      return NucleusTestUtils.getConfigpath(this.getClass(), this.getClass().getName(), true);
    }
    }
    
    1. 通过扩展基类编写测试用例 -
    2. public class BizDropletTest extends BaseTestCase {
      private BizDroplet bizDroplet;
      
      @Before
      public void setUp() throws Exception {
      super.setUp();
      mNucleus = NucleusTestUtils.startNucleusWithModules(new String[] { "DSS", "DPS", "DAFEAR" }, this.getClass(),
      this.getClass().getName(), "com/ebiz/market/support/droplet/BizDroplet");
      autoSuggestDroplet = (AutoSuggestDroplet) mNucleus.resolveName("com/ebiz/market/support/droplet/BizDroplet");
      try {
      bizDroplet.doStartService();
      } catch (ServiceException e) {
      fail(e.getMessage());
      }
      }
      
      /**
      Other methods
      */
      }
      

      那么,Mockito如何处理这些?同样,对我来说,目标是完全取代ATG Dust和Mockito,因为ATG Dust由于巨大的依赖性而在运行测试中花费了大量时间。

      感谢。

1 个答案:

答案 0 :(得分:7)

使用Mockito,您不会设置Nucleus或其他依赖项(除非您需要它)。您只需模拟需要使用的对象。

考虑一个简单的类ProductUrlDroplet,它从存储库中检索产品,然后根据此输出URL。 service方法看起来像这样:

public void service(DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse) throws ServletException, IOException {
    Object product = pRequest.getObjectParameter(PRODUCT_ID);

    RepositoryItem productItem = (RepositoryItem) product;
    String generatedUrl = generateProductUrl(pRequest, productItem.getRepositoryId());

    pRequest.setParameter(PRODUCT_URL_ID, generatedUrl);
    pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);
}

private String generateProductUrl(DynamoHttpServletRequest request, String productId) {

    HttpServletRequest originatingRequest = (HttpServletRequest) request.resolveName("/OriginatingRequest");
    String contextroot = originatingRequest.getContextPath();

    return contextroot + "/browse/product.jsp?productId=" + productId;
}

一个简单的测试类将是:

public class ProductUrlDropletTest {

@InjectMocks private ProductUrlDroplet testObj;
@Mock private DynamoHttpServletRequest requestMock;
@Mock private DynamoHttpServletResponse responseMock;
@Mock private RepositoryItem productRepositoryItemMock;

@BeforeMethod(groups = { "unit" })
public void setup() throws Exception {

    testObj = new ProductUrlDroplet();
    MockitoAnnotations.initMocks(this);
    Mockito.when(productRepositoryItemMock.getRepositoryId()).thenReturn("50302372");
}

@Test(groups = { "unit" })
public void testProductURL() throws Exception {
    Mockito.when(requestMock.getObjectParameter(ProductUrlDroplet.PRODUCT_ID)).thenReturn(productRepositoryItemMock);

    testObj.service(requestMock, responseMock);
    ArgumentCaptor<String> argumentProductURL = ArgumentCaptor.forClass(String.class);
    Mockito.verify(requestMock).setParameter(Matchers.eq(ProductUrlDroplet.PRODUCT_URL_ID), argumentProductURL.capture());
    Assert.assertTrue(argumentProductURL.getValue().equals("/browse/product.jsp?productId=50302372"));
}

}   

关键组件是您需要初始化要测试的类(testObj)。然后,您只需为要使用的对象的每个输入参数构建响应(在这种情况下,productRepositoryItemMock代表RepositoryItemproductRepositoryItemMock.getRepositoryId()返回String,然后你可以测试一下。)

您还会注意到此测试仅验证service方法,而不验证单个方法。你是如何做到的取决于你,但一般来说我一直专注于测试我的servicehandleXXX方法。

测试XXXManager,XXXUtil和XXXService类都将有自己的测试,应该“嘲笑”到飞沫和压榨机中。对于这些,我会为每种方法编写测试。

当你需要模拟PowerMockito方法和类时,

static才真正出现在图片中,文档就足以解释这一点。