正在使用Assert.assertTrue(true);并断言Assert.fail(); JUnit测试的良好实践?

时间:2016-04-20 09:05:37

标签: java unit-testing junit assertion

这是使用Assert.assertTrue(true)的好或坏做法;和JUnit测试中的Assert.fail()以及为什么?

我知道还有规则@Test(expected = Exception.class),但你可以有更多的异常可以在测试方法上引发,如果你不想为一个测试方法有多种测试方法,这个可能是选择。

用例是这样的:你测试的方法可以引发零,一个或多个异常(在例子中使它变得简单只有一个)并且你想测试一下调用是好的情况所以没有异常应该是如果你进入catch块你会引发Assert.fail();那么你想要在引发异常的情况下测试用例,所以你要调用catch块Assert.assertTrue(true);说“是的,这就是我想要的”。从测试中你可以看到它应该在一个测试方法失败时以及当你运行测试时它是否真的像你想要的那样。
问题是:这是好的还是坏的做法?为什么?

public void fooMethod(boolean paramenter) {
  if(false) {
    throw new Exception();
  }
}

@Test
public void testFooMethod() {

  try {
     myTestedClassMock.fooMethod(true); //should not raise exception
  } catch(Exception e) {
    Assert.fail();
  }  

  try {
    myTestedClassMock.fooMethod(false); //should raise exception
  } catch (Exception e) {
     Assert.assertTrue(true);
  }

}

4 个答案:

答案 0 :(得分:2)

使用fail()是一种很好的做法,但不像你这样做。这是因为如果发生异常,您希望让测试失败。这可以不用捕获此异常。如果出现,则测试失败。

在第二种情况下,而不是在方法调用后使用assertTrue(true)添加fail()

myTestedClassMock.fooMethod(true); //should not raise exception

try {
    myTestedClassMock.fooMethod(false); //should raise exception
    Assert.fail("Exception expected!");
} catch (Exception e) {
    // exception handling
}

这使您的意图更加明确,如果没有抛出异常,您会看到测试失败。

答案 1 :(得分:2)

您可以随时忽略Assert.assertTrue(true)因为assertTrue是出于不同目的而设计的。它可以检查涉及多个布尔项的一般条件,例如

Assert.assertTrue(t == null ||| minSize < 0 || t.size() > minSize);

断言常量true总是成功而没有跟踪,因此您可以从代码中完全删除此行。通过在必须抛出异常的测试代码行之后立即放置Assert.fail();来完成捕获预期异常 not 的情况,并显示一条消息,指示尚未抛出预期的异常

  

如果你不想为一种测试方法提供多种测试方法,那么这可能是一种选择。

通常,“zillion测试方法”是更好的选择。作为替代方案,您可以在测试中捕获ExceptionRuntimeException,而不是捕获每个异常。这在生产代码中是一个值得怀疑的做法,但是当你必须确保没有抛出异常时,它在测试代码中绝对没问题。

然而,拥有Assert.fail();并不是一种不常见的捷径,通常也是可以接受的。最好添加描述失败原因的消息,以便维护代码的人不必阅读测试以查看发生的情况。当您捕获异常时,它的消息是测试失败消息的良好候选者。

答案 2 :(得分:1)

第二种情况是否缺少某些东西? 我宁愿做下一次检查:

  try {
    myTestedClassMock.fooMethod(false);
    Assert.fail("should raise exception");
  } catch (Exception e) {
    //Check if this is the exception you expected
  }

第一种情况怎么样,如果抛出异常,无论如何它都会失败,所以不需要Assert.fail()try-catch阻止

答案 3 :(得分:1)

有关源代码的一些良好做法。

首先:每个测试方法中只有一个断言。因此,当该方法失败时,您会立即知道要查找的位置。

这也有助于解决您的问题:

@Test
public void testFooMethodThatShouldNotThrow() throws WhatEverException {
   bar.foo(true)

因此,如果foo()抛出上面的代码,则单元测试失败。我们添加了一个throws子句并不重要。

当您预期会抛出异常时;然后这样说:

@Test(expected=WhateverException.class)
public void testFooMethodThatShouldThrow() {
  bar.foo(false);
}

如果要检查抛出异常的某些属性;然后你会做一个

@Test
public void bla {
  try {
    bar.foo();
    fail("should have thrown");
  catch (WhateverException e) {
    assertThat(e.getMessage(), is("bla blub flubber"));
  }

例如。

最后:只有一个人需要的断言:断言。忘记所有其他人;并学会使用那个。