使用 Mockito 编写 ATG 测试用例 [英] Using Mockito for writing ATG test case

查看:18
本文介绍了使用 Mockito 编写 ATG 测试用例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道使用 Mockito 为 ATG 编写单元测试用例吗?我在护目镜时遇到了以下讨论-用于 ATG 开发的自动化单元测试使用PowerMock获取ATG Nucleus inNPE测试结果

但需要帮助设置 Nucleus 和其他依赖项(DAS、DPS、DSS 等)以及使用 Mockito 的液滴示例测试类.

我们正在使用 ATG Dust,我们必须设置所有依赖项.我想知道我们是否可以用 Mockito 完全替换 ATG Dust.这是我们如何编写测试用例的示例 -

  1. 用于设置 Nucleus 的基类 -

<块引用>

com.ebiz.market.support 包;导入java.io.File;导入 java.util.Arrays;导入 atg.nucleus.NucleusTestUtils;导入 atg.test.AtgDustCase;导入 atg.test.util.FileUtil;公共类 BaseTestCase 扩展 AtgDustCase {公共 atg.nucleus.Nucleus mNucleus = null;私有最终字符串 ATGHOME="C://ATG/ATG9.4//home";私人最终字符串 ATGHOMEPROPERTY = "atg.dynamo.home";受保护的 void setUp() 抛出异常 {super.setUp();字符串 dynamoHome = System.getProperty(ATGHOMEPROPERTY);如果(dynamoHome == null)System.setProperty(ATGHOMEPROPERTY, ATGHOME);文件配置路径 = 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");}公共文件 getConfigPath() {返回 NucleusTestUtils.getConfigpath(this.getClass(), this.getClass().getName(), true);}}

  1. 通过扩展基类编写测试用例 -

<块引用>

公共类 BizDropletTest 扩展 BaseTestCase {私人 BizDroplet bizDroplet;@前公共 void setUp() 抛出异常 {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");尝试 {bizDroplet.doStartService();} 捕捉(服务异常 e){失败(e.getMessage());}}/**其他方法*/}

那么,Mockito 如何处理这些问题?同样,对我来说,目标是完全用 Mockito 替换 ATG Dust,因为 ATG Dust 需要大量时间来运行测试,因为依赖关系很大.

谢谢.

解决方案

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

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

public void service(DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse) 抛出 ServletException, IOException {对象产品 = pRequest.getObjectParameter(PRODUCT_ID);RepositoryItem productItem = (RepositoryItem) 产品;字符串 generatedUrl = generateProductUrl(pRequest, productItem.getRepositoryId());pRequest.setParameter(PRODUCT_URL_ID, generatedUrl);pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);}私有字符串 generateProductUrl(DynamoHttpServletRequest 请求,字符串 productId){HttpServletRequest originatingRequest = (HttpServletRequest) request.resolveName("/OriginatingRequest");字符串 contextroot = originatingRequest.getContextPath();返回 contextroot + "/browse/product.jsp?productId=" + productId;}

一个简单的测试类将是:

公共类 ProductUrlDropletTest {@InjectMocks 私有 ProductUrlDroplet testObj;@Mock private DynamoHttpServletRequest requestMock;@Mock private DynamoHttpServletResponse responseMock;@Mock private RepositoryItem productRepositoryItemMock;@BeforeMethod(groups = { "unit" })公共无效设置()抛出异常{testObj = new ProductUrlDroplet();MockitoAnnotations.initMocks(this);Mockito.when(productRepositoryItemMock.getRepositoryId()).thenReturn("50302372");}@Test(groups = { "unit" })公共无效 testProductURL() 抛出异常 {Mockito.when(requestMock.getObjectParameter(ProductUrlDroplet.PRODUCT_ID)).thenReturn(productRepositoryItemMock);testObj.service(requestMock, responseMock);ArgumentCaptor<字符串>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 类都将有自己的测试,并且应该模拟"到 Droplet 和表单处理程序中.不过对于这些,我会为每种方法编写测试.

PowerMockito 仅在您需要模拟 static 方法和类时才真正发挥作用,并且文档足以解释这一点.

Does anyone have idea about writing unit test case for ATG using Mockito? I came across following discussions while goggling - Automated unit tests for ATG development and Using PowerMock to obtain the ATG Nucleus in testing results in NPE

But need a help in setting up Nucleus and other dependencies (DAS, DPS, DSS etc.) and a sample test class for droplet using Mockito.

We are using ATG Dust where we have to set all the dependencies. I am wondering if we can replace ATG Dust completely with Mockito. Here is the example how we are writing the test cases -

  1. A Base class for setting Nucleus -

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. Writing the test case by extending the base class -

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
*/
}

So, how Mockito can handle these? Again, for me the target is to replace ATG Dust with Mockito completely because ATG Dust take lot of time in running tests due to huge dependencies.

Thanks.

解决方案

Using Mockito you don't setup Nucleus or other dependencies (unless you need it). You simply mock the objects that you need to use.

Consider a simple class ProductUrlDroplet that retrieves a product from the repository and then outputs a url based on this. The service method would look something like this:

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;
}

A simple test class for this will then be:

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"));
}

}   

The key components are that you need to initialise the class you want to test (testObj). You then simply construct the response for each of the input parameters of the objects you are going to use (in this case productRepositoryItemMock represents the RepositoryItem and productRepositoryItemMock.getRepositoryId() returns a String that you can then test against later).

You will also notice that this test only validates the service method and not the individual methods. How you do it is up to you but generally I've been focused on testing my service and handleXXX methods in the formhandlers and droplets.

Testing the XXXManager, XXXUtil and XXXService classes will all have their own tests and should be 'mocked' into the droplets and formhandlers. For these I would write tests for each method though.

PowerMockito only really comes into the picture when you need to mock static methods and classes and the documentation does enough to explain that.

这篇关于使用 Mockito 编写 ATG 测试用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆