JUnit4 fail()就在这里,但是pass()在哪里?

Eug*_*ene 72 java junit

fail()JUnit4库中有一个方法.我喜欢它,但缺乏pass()图书馆中没有的方法.为什么会这样?

我发现我可以使用,assertTrue(true)但看起来仍然不合逻辑.

@Test
 public void testSetterForeignWord(){
  try {
   card.setForeignWord("");
   fail();
  } catch (IncorrectArgumentForSetter ex){
  }

 // assertTrue(true);
 }
Run Code Online (Sandbox Code Playgroud)

Hor*_*ux7 65

return在测试完成并通过的任何时候调用语句.

  • +1必须是正确的答案(在大多数情况下,除了预期,超时等) (3认同)

Col*_*inD 61

只要测试没有抛出异常,它就会传递,除非您的@Test注释指定了预期的异常.我想pass()可以抛出一个特殊的异常,JUnit总是将其解释为传递,以便使测试短路,但这会违背通常的测试设计(即假设成功并且只有在断言失败时才会失败),并且,如果人们得到了它最好使用pass()它的想法,它会显着减慢大量的传递测试(由于异常创建的开销).失败的测试不应该是常态,所以如果他们有这样的开销就没什么大不了的.

请注意,您的示例可以像这样重写:

@Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
  card.setForeignWord("");
}
Run Code Online (Sandbox Code Playgroud)

此外,您应该支持使用标准Java异常.你IncorrectArgumentForSetter可能应该是一个IllegalArgumentException.

  • fail()方法和assertX()方法实际上只是抛出一个AssertionError,导致测试方法不正确地退出.这就是成功回归表明成功的原因...... (4认同)

Gro*_*tav 5

我认为这个问题需要更新的答案,因为这里的大多数答案都已经过时了。

首先,对OP的问题:

我认为,将“预期的例外”概念引入JUnit是一个不好的举动,因为它可以在任何地方引发,并且可以通过测试。如果您抛出(并断言)非常特定于域的异常,那么它会起作用,但是当我处理需要绝对完美的代码时,我只会抛出此类异常,-大多数APIS只会抛出诸如IllegalArgumentException或的内置异常。IllegalStateException。如果您进行的两次调用都可能会引发这些异常,则@ExpectedException即使测试的错误行引发了异常,注释也会使您的测试处于绿色状态!

对于这种情况,我已经编写了一个我肯定在这里编写过其他类的类,这是一个assertThrows方法:

public class Exceptions {
    private Exceptions(){}

    public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
        try{
            actionThatShouldThrow.run();
            fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
        }
        catch(Exception e){
            if ( ! expectedException.isInstance(e)) {
                throw e;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果抛出异常,此方法仅返回,从而允许您在测试中进行进一步的声明/验证。

使用Java 8语法,您的测试看起来非常不错。下面是使用该方法的模型的较简单测试之一:

@Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
    //setup
    AxisRange range = new AxisRange(0,100);

    //act
    Runnable act = () -> range.setLowerBound(200);

    //assert
    assertThrows(IllegalArgumentException.class, act);
}
Run Code Online (Sandbox Code Playgroud)

这些测试有些奇怪,因为“ act”步骤实际上并未执行任何操作,但是我认为含义仍然很清楚。

在Maven上还有一个很小的小库,叫做catch-exception,它使用模仿式语法来验证是否抛出了异常。看起来不错,但我不喜欢动态代理。就是说,那里的语法是如此巧妙,它仍然很诱人:

// given: an empty list
List myList = new ArrayList();

// when: we try to get the first element of the list
// then: catch the exception if any is thrown 
catchException(myList).get(1);

// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;
Run Code Online (Sandbox Code Playgroud)

最后,对于遇到这种情况的情况,如果满足一些条件,有一种方法可以忽略测试。

现在,我正在通过名为JNA的java native-library-loading-library获取一些DLL,但是我们的构建服务器在ubuntu中。我喜欢尝试用JUnit测试来推动这种开发-即使目前它们离“单元”还很远。我想做的是如果我在本地计算机上运行测试,但是如果我们在ubuntu上则忽略测试。JUnit 4确实为此提供了一项规定Assume

@Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
    //this line will cause the test to be branded as "ignored" when "isCircleCI" 
    //(the machine running ubuntu is running this test) is true.
    Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
    //an ignored test will typically result in some qualifier being put on the results, 
    //but will also not typically prevent a green-ton most platforms. 

    //setup
    URL url = DLLTestFixture.class.getResource("USERDLL.dll");
    String path = url.toURI().getPath();
    path = path.substring(0, path.lastIndexOf("/"));

    //act
    NativeLibrary.addSearchPath("USERDLL", path);
    Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);

    //assert
    assertThat(dll).isNotNull();
}
Run Code Online (Sandbox Code Playgroud)