有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Liferay中的javajunit和mock

我需要使用Mockito、PowerMock或smth进行JUnit测试,但我不知道从何开始。我创建了测试文件夹,设置了mockito,但是接下来我该怎么做呢?我找不到任何例子,所以我被它绊住了。你能告诉我如何编写这个JUnit测试吗,或者至少给出一些想法

public void deleteAuthor(ActionRequest actionRequest, ActionResponse actionResponse)
        throws SystemException, PortalException {
    long authorId = ParamUtil.getLong(actionRequest, "authorId");
    AuthorLocalServiceUtil.deleteAuthor(authorId);
    SessionMessages.add(actionRequest, "deleted-author");
    log.info(DELETE_SUCCESS);

}

或者这个:

public void addAuthor(ActionRequest actionRequest, ActionResponse actionResponse) 
        throws IOException, PortletException, SystemException {

    String authorName=ParamUtil.getString(actionRequest,"authorName");
    Author author=AuthorLocalServiceUtil.createAuthor(CounterLocalServiceUtil.increment());
    author.setAuthorName(authorName);
    author=AuthorLocalServiceUtil.addAuthor(author);        
}

另外,我是个新手,一生中只做过一次JUnit测试,所以我对好的建议很感兴趣。提前谢谢


UPD:

我试着这样做:

private BookAndAuthor portlet;

@Before
public void setUp() {
    portlet = new BookAndAuthor();
}


@Test
public void testDeleteBookOk() throws Exception {
    PowerMockito.mockStatic(BookLocalServiceUtil.class);
    long id = 1;
    Book book = BookLocalServiceUtil.createBook(id);

    ActionRequest actionRequest = mock(ActionRequest.class);
    ActionResponse actionResponse = mock(ActionResponse.class);

    when(BookLocalServiceUtil.deleteBook(book)).thenReturn(null);
    Book result = BookLocalServiceUtil.deleteBook(book);
    assertEquals(result, null);
}

。。。但是没有成功


共 (2) 个答案

  1. # 1 楼答案

    这将是一个不受欢迎的答案,但是

    我发现使用大量模拟对象的JUnit测试并不是特别有用。当查看测试的setUp()方法的大小时,平衡就出现了:它越长,测试的值就越小。在portlet世界中,您必须使用大量模拟,并且您将比修复仅在创建此类测试期间发现的问题更忙于镜像运行时环境(并纠正您对它所做的假设)

    话虽如此,这是我的处方

    1. 构建portlet时要记住一件事:portlet是一种UI技术。UI本质上很难自动测试。您被困在JSR-286标准和业务层之间——这两个层可能不适合在测试中连接它们

    2. 让您的UI层代码保持简单到可笑的程度,这样您就可以只进行一点代码检查。与JUnit测试中庞大的setUp()例程相比,您将从中学到更多

    3. 找出有意义的UI层代码。将其提取到自己的实用程序类或方法中。测试-请注意,您甚至不需要完整的PortletRequest对象,只需使用它所需的实际数据

    4. 在此基础上创建集成测试。这些将利用整个堆栈,即部署在测试环境中的应用程序。他们将提供冒烟测试,以查看您的代码是否实际工作。但要确保测试正确的线路不会让你们慢下来:复杂的代码object.setStreet(request.getParameter("street"));不应该被测试,而应该被检查——它应该是明显正确的或者明显错误的

    5. 使用适当的编码标准,使审查更容易。例如,如果输入字段中包含数据,请将其命名为“street”,而不是“input42”

    记住这些:每当您编写一个portlet,其中包含您认为应该测试的代码时:提取它。无需模拟portlet对象或业务层。测试提取的代码。portlet方法中的第二个{ code block }可能足以证明提取到一个单独的类/方法的合理性,该类/方法通常可以进行简单的测试——这些测试将完全独立于Liferay,如果失败,将教给您很多关于代码的知识,并且比那些设置大量模拟对象的测试更容易理解

    我宁愿在琐碎的测试上犯错误,也不愿意在过于复杂的测试上犯错误:过于复杂的测试会让你慢下来,而不是提供有意义的洞察力。它们通常只会失败,因为关于运行时环境的假设是错误的,需要更正

  2. # 2 楼答案

    我们正在使用以下设置运行JUnit测试:

    i.在portlet中的docroot旁边创建test文件夹

    ii添加unit文件夹以测试并在其中创建package

    iii.使用以下配置在test文件夹中创建portal-ext.properties文件:

    jdbc.default.driverClassName=com.mysql.jdbc.Driver
    jdbc.default.url=jdbc:mysql://localhost:3309/db_name?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
    jdbc.default.username=your_username
    jdbc.default.password=your_password
    
    jdbc.default.automaticTestTable=C3P0TestTable
    jdbc.default.idleConnectionTestPeriod=36000
    jdbc.default.maxIdleTime=1200
    

    iv.创建一个套件类(比如AbcSuite.java),如下所示:

    package x.x.x;
    
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;
    
    import com.liferay.portal.util.InitUtil;
    
    @RunWith(Suite.class)
    @Suite.SuiteClasses({
        // Where AxTest.class would be your test class name
        A1Test.class, A2Test.class, AxTest.class
    })
    
    public class AbcSuite {
    
        @BeforeClass
        public static void setUp() throws Exception {
            // Loading properties and establishing connection with database
            InitUtil.initWithSpring();
            System.out.println("X Portlet's Test Suite Execution : Started.");
        }
    
        @AfterClass
        public static void tearDown() {
            System.out.println("X Portlet's Test Suite Execution : Completed.");
        }
    }
    

    v.创建一个测试类(比如A1Test.java),如下所示:

    package x.x.x;
    
    import java.util.ArrayList;
    
    import org.junit.Assert;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    public class A1Test {
    
        @BeforeClass
        public static void setUp() throws Exception {
            System.out.println("Test Running : A1Test");
        }
    
        @Test
        public void testAddAuthor() {
            Author author = AuthorLocalServiceUtil.createAuthor(
                CounterLocalServiceUtil.increment());
            author.setAuthorName("Testcase Author");
            author = AuthorLocalServiceUtil.addAuthor(author);
    
            Assert.assertNotNull(author);
            Assert.assertTrue(author.getAuthorId() > 0);
        }
    }
    

    就这样!您可以使用以下命令同时执行所有测试用例:

    ant test -Dtest.class=AbcSuite*
    

    或单独作为:

    ant test -Dtest.class=A1Test*