大多数人都知道单元测试的重要性和好处,以及为什么要在进行的项目中使用它们。 而且,大多数人不喜欢在他们从事的项目中编写单元测试。 TDD的人当然处于另一面,但根据我的经验,他们在IT行业中是少数派。
说到我,我和大多数人在一起:-)。 我知道为什么进行单元测试会很好,以及如何提高代码和项目的质量。 我知道您为什么应该投资于它们,但是我对编写单元测试并不满意,这不是让我彻夜难眠的原因。 我更喜欢创建出色的软件并解决复杂的问题,然后编写单元测试。 这就是为什么我一直在寻找可以帮助我获得更多,更好的单元测试的东西,而这方面的工作却少了很多,因为最后您应该在项目中进行单元测试。
Junit Params是可以帮助您以更少的时间编写更好的单元测试的那些事情之一。
您为什么要关心Junit Params?
让我们想象一下,我们有一个简单的类Person,它具有名字和姓氏。 业务要求是,姓氏和名字不能为null或空字符串。
我们可以结束与这一课类似的课
public class Person { private final String firstName; private final String lastName; public Person(String first, String last) { if (first == null || first.trim().isEmpty() || last == null || last.trim().isEmpty() ) { throw new RuntimeException( "bad input" ); } this .firstName = first; this .lastName = last; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } }
下一步是确保代码按预期工作,并且考虑了所有极端情况。
我们当然希望使用单元测试来涵盖所有可能性,但是如果您考虑一下,我们将有很多重复的代码,在这些代码中,我们会测试所有可能性的名字,然后是姓氏,然后是所有组合,依此类推我们要涵盖所有边缘情况。 在这个简单的类中,我们将在单元测试中得到更多的代码,然后在业务逻辑中得到更多的代码。
让我们看看JUnit Params如何帮助我们。
初始化设定
为了使用Junit Params,您只需像添加其他任何库一样添加依赖项
<dependency> <groupId>pl.pragmatists</groupId> <artifactId>JUnitParams</artifactId> <version> 1.1 . 1 </version> <scope>test</scope> </dependency>
之后,我们可以开始在单元测试中使用JUnit Params
使用JUnit参数进行JUnit测试
现在让我们使用JUnit Params编写一些单元测试。
创建简单的测试类PersonTest并添加@RunWith( JUnitParamsRunner.class )
@RunWith (JUnitParamsRunner. class ) public class PersonTest { ....... }
现在,我们可以编写简单的单元测试来验证我们的类。 让我们先检查一下是否一切都很好,如果我们将null用作名字
@Test (expected = RuntimeException. class ) public void fistNameNull() { Person p = new Person( null , "dummyLast" ); }
关于JUnit Params的伟大之处在于,我们仍然可以编写标准的单元测试,并将其与JUnit Params结合使用。
为了在此单元测试中利用JUnit参数,我只需要添加具有适当值的@Parameters ,然后它将看起来像这样
@Test (expected = RuntimeException. class ) @Parameters ({ "" , " " , " " , " " }) public void fistNameParamaters(String param) { Person p = new Person(param, "dummyLast" ); }
使用此代码,我进行了4个单元测试,以验证代码中的值“”,“”,“”,“”和“”。
这已经显示了JUnit参数是多么有用,因为您只编写了一个单元测试,并且它将针对您参数的所有不同可能性执行该测试。
将参数传递给多个输入参数
如果我们要传递输入值(名字和姓氏)的参数,会发生什么情况。 在这种情况下,我们会做这样的事情
@Test (expected = RuntimeException. class ) @Parameters ({ " " , " " , // firstName, lastName " " , "" , " " , " " , " " , " " }) public void fistNameLastNameParamaters(String first, String last) { Person p = new Person(first, last); }
由于有两个输入参数,因此将提供的值一分为二并用作输入。
如您所见,为多个参数提供输入非常容易,尽管通过这种方式,我们需要提供要测试的所有组合。
以用户友好的方式将参数传递给多个输入参数
如果说老实话,尽管上面的测试对于多个输入参数可以很好地工作,但是它不是非常用户友好的。 让我们在下一个示例中修复该问题
@Test (expected = RuntimeException. class ) @Parameters ({ " | " , " |" , " | " , " | " }) public void fistNameLastNameParamaters2(String first, String last) { Person p = new Person(first, last); }
现在,可以更清楚地知道每次迭代中哪个值将用于哪个输入参数。
使用非字符串值作为输入参数
到目前为止,所有参数都是字符串。 如果我们的输入参数不是String或容易从String转换为String的东西,例如null值,该怎么办。
在这种情况下,我们可以使用命名参数
@Test (expected = RuntimeException. class ) @Parameters (named = "emptyStrings" ) public void namedParamaters(String first, String last) { Person p = new Person(first, last); } @NamedParameters ( "emptyStrings" ) private Object[] emptyStrings() { return new Object[]{ new Object[]{ null , "" }, new Object[]{ "" , null }, new Object[]{ " " , " " }, new Object[]{ " " , " " } }; }
参考
这篇文章中提到的代码示例可以在此网址上找到
- https://github.com/vladimir-dejanovic/junit-params-blog-examples
翻译自: https://www.javacodegeeks.com/2019/02/writing-unit-tests-time-junit-parameters.html