Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否有创建JUnit测试用例的过程?_Java_Unit Testing - Fatal编程技术网

Java 是否有创建JUnit测试用例的过程?

Java 是否有创建JUnit测试用例的过程?,java,unit-testing,Java,Unit Testing,我对Java开发相当陌生,今天是我第一次配对程序来创建测试用例。他们很友好,大声说出了他们的想法,以解释为什么要做某些事情(例如,创建一个带参数的构造函数,而不仅仅是一个默认构造函数,等等) 虽然我可能会保留我今天看到/听到的内容的40%,但我想知道是否有一套步骤/指导方针可以遵循,最终结果是一个测试用例,这将是一个很好的起点。我知道人们通常的反应 每个商店都有自己的标准 有个人喜好和工具 取决于测试是针对您自己的类还是针对遗留类,等等 不管是哪种方式,我都这么想,也这么问了各位议员 下面是我记

我对Java开发相当陌生,今天是我第一次配对程序来创建测试用例。他们很友好,大声说出了他们的想法,以解释为什么要做某些事情(例如,创建一个带参数的构造函数,而不仅仅是一个默认构造函数,等等)

虽然我可能会保留我今天看到/听到的内容的40%,但我想知道是否有一套步骤/指导方针可以遵循,最终结果是一个测试用例,这将是一个很好的起点。我知道人们通常的反应

  • 每个商店都有自己的标准
  • 有个人喜好和工具
  • 取决于测试是针对您自己的类还是针对遗留类,等等
  • 不管是哪种方式,我都这么想,也这么问了各位议员

    下面是我记下的一些笔记的一个片段,从回答的角度展示了我的想法

  • 使用Mockito,您无法模拟使用方法创建的对象,因此请尝试获取构造函数以获取这些对象。这将允许您模拟它们,然后将它们传递给该方法以便于测试
  • Mockito不处理静态方法,但您可以创建一个调用静态方法的包装器类。现在,这个新的包装器类不使用任何静态方法,您测试的类将使用它而不是静态方法。现在,您可以使用when/thenReturn,而不必直接处理静态方法
  • 模拟时,声明将由类级别的所有测试用例使用的变量。然后在setUp()中模拟这些类;这种方法确保常用的模拟始终处于已知状态,并且不会被以前的测试修改
  • 如果说得不够,请使用好的变量名(例如listWithOneCar、listWithNoCars等)
  • 由于测试用例有时基于真值表,因此尝试将其包含在测试方法名称中(例如,ensureCanDrive_Car_0_with validkey_0(),ensureCanDrive_Car_1_with validkey_1(),等等)。如果您已经通过快速视觉扫描捕获了大量测试用例,那么这将有助于您进行视觉扫描。完成后,只需添加边缘案例
  • “验证”使用不足,请尝试在测试用例中使用更多
  • 单个测试用例应该只有不同于测试用例的代码,而没有重复的代码。这使得它更易于理解和维护/扩展
  • 你明白了。
    这些都是我的笔记,但我想知道是否有人有一个进化的列表?

    你的列表中有非常不同的东西。甚至对于其中一个主题,“完整”的列表也不太可能。大多数人会写一本书,可能是倍数。这是我的书籍(和其他文档)列表,它们构成了一个比较完整的列表

    • 有些似乎是关于一般良好的编码实践。例如,建议通过构造函数使用依赖注入(#1);好名字的重要性(#4)。很难列出一个完整的清单,但是有一些重要的书籍。我推荐

      • 罗伯特·C·马丁的《干净的代码》

      • 安德鲁·亨特和大卫·托马斯的实用程序员

      • 约书亚·布洛赫的《有效的Java》

    • 有些是关于Mockito的局限性,只需浏览文档和一些博客文章即可。您可能还想看看PowerMock,它试图修复Mockito和其他模拟框架的一些(大多数?)技术限制。只要阅读他们所做的事情,你就会更好地理解Mockitos的局限性

    • 有些是关于设计测试、使代码可测试等等。你可以考虑以下的书籍:

      • xUnit测试模式:GerardMeszaros重构测试代码

      • 测试驱动:Lasse Koskela为Java开发人员提供的TDD和验收TDD

      • 测试驱动开发:以Kent Beck为例


    您关注的是单元测试的一个方面,即模拟。当您不想(或不想)测试一小部分代码时,您可以进行模拟,例如数据库查询或日志记录实用程序

    根据我的经验,单元测试有两种风格:集成和单元测试

    重要的是,无论是单元测试的哪种风格,您都必须理解:

    • 方法在快乐道路上的行为是什么,以及
    • 边缘情况下的行为是什么
    在编写单元测试时,我将使用Mockito之类的模拟库,但我不只是将自己排除在外。有时,使用Mockito不适合您想要进行的测试(100次中有99次,是在集成测试中。不要这样做。),但当我只想模拟重bean/object/DAO的行为进行快乐路径或边缘案例测试时,它非常方便

    我倾向于将测试分为三个不同的部分:

    • 我的礼物,包括设置要测试的方法,包括模仿时的行为
    • 我的“when I do this”子句,它本质上只是执行该方法
    • 我的验证步骤,包括测试结果的一个方面
    例如,假设我想测试这个方法的行为

    public List<String> shortenNamesFromDatabase(final int maxLength) {
        List<String> names = dao.executeQuery("SELECT name from dbNames");
        List<String> result = new ArrayList<String>();
        for(String name : names) {
            result.add(name.substring(0, maxLength);
        }
        return result;
    }
    
    public List shortenNamesFromDatabase(final int maxLength){
    列表名称=dao.executeQuery(“从数据库名称中选择名称”);
    列表结果=新建ArrayList();
    for(字符串名称:名称){
    result.add(name.substring(0,maxLength);
    }
    返回结果;
    }
    
    我有一个对数据库的调用和一些转换逻辑。我不想在这一层验证数据库信息,所以我将模拟它。在集成测试中,我确保对数据库进行调用,这会从数据库中获取每个名称

    //happy path test!
    @Test
    public void shortenNamesFromDatabase_namesAreOnly3CharactersLong() {
        //given
        final int length = 3;
        List<String> dbResult = Arrays.asList("Alpha","Beta", "Gamma", "Del", "Zeta12345");
        Dao daoMock = mock(Dao.class);
        when(daoMock.executeQuery("SELECT name from dbNames")).thenReturn(dbResult);
        SomeClass testObj = new SomeClass();
    
        //when
        List<String> result = testObj.shortenNamesFromDatabase(length);
    
        //then
        for(String name : result) {
            assertTrue("Name was too long!", length <= name.length());
        }
    }
    
    //快乐路径测试!
    @试验
    来自数据库的public void shortennames\u名称仅为3个字符
    
    //edge-case-why-would-you-ever-do-this-for-real test
    @Test
    public void shortenNamesFromDatabase_zeroLengthStringsTransformed() {
        //given
        final int length = 0;
        List<String> dbResult = Arrays.asList("Alpha","Beta", "Gamma", "Del", "Zeta12345");
        Dao daoMock = mock(Dao.class);
        when(daoMock.executeQuery("SELECT name from dbNames")).thenReturn(dbResult);
        SomeClass testObj = new SomeClass();
    
        //when
        List<String> result = testObj.shortenNamesFromDatabase(length);
    
        //then
        for(String name : result) {
            assertTrue("Name was WAY too long!", length <= name.length());
        }
    }