JUnit AssertionError - 未抛出预期异常

时间:2018-01-16 09:11:45

标签: java unit-testing junit mockito junit4

我试图熟悉JUnit / Mockito并使用以下方法尝试一些单元测试:

public FSDataInputStream getObj(String hName, Path p) throws IOException {

    String myKey = pathToKey(hName, p);
    FileStatus status = memoryCache.getStatus(p.toString());
    if (status == null) {
      status = getStatus(hName, p, "getObj");
    }
    if (status.isDirectory()) {
        throw new FileNotFoundException("Can't open " + path
  + " because it is a directory");
    }
    InputStream inputStream = new InputStream(bucket, myKey,
    status.getLen(), client, readAhead, inputPolicy);

    return new FSDataInputStream(inputStream);
}

如果status.isDirectory == true,我希望测试是否抛出了fileNotFoundException。

我相信我必须调用getObj()方法,对于if (status.isDirectory())我必须确保值为true。我认为这是通过when(fileStatus.isDirectory()).thenReturn(true);来完成的。我不确定如何调用该方法并确保这样做。

到目前为止,我已经获得了这个JUnit,但它似乎不正确,因为它返回了以下错误:

public class ClientTest {
    MemoryCache memoryCache = mock(MemoryCache.class);
    FileStatus fileStatus = mock(FileStatus.class);

    @Rule
    public final ExpectedException exception = ExpectedException.none();

    @Test
    public void getObjTest() throws Exception {
        Path path = new Path("xyz://aa-bb-cc/data7-1-23-a.txt");

        when(memoryCache.getFileStatus(path.toString())).thenReturn(fileStatus);
        when(fileStatus.isDirectory()).thenReturn(true);
        exception.expect(FileNotFoundException.class);
    }
}
  

java.lang.AssertionError:抛出java.io.FileNotFoundException实例的预期测试       在org.junit.Assert.fail(Assert.java:88)       at org.junit.rules.ExpectedException.failDueToMissingException(ExpectedException.java:263)       at org.junit.rules.ExpectedException.access $ 200(ExpectedException.java:106)       at org.junit.rules.ExpectedException $ ExpectedExceptionStatement.evaluate(ExpectedException.java:245)       在org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:91)       at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)       在org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)       在org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)       在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)       在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)       在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)       在org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)       在org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)       在org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)       在org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)       在org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)       在org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)       在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)       在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

有人可以告诉我做错了吗?

2 个答案:

答案 0 :(得分:2)

1)取消注释第一个when语句,因为下一个when设置有效。

2)调用测试中的方法

3)(可选)使用注释进行模拟:

public class ClientTest {

    @Spy
    @InjectMocks
    private Client clientSpy = new Client();

    @Mock
    MemoryCache memoryCache;
    @Mock
    FileStatus fileStatus;

    @Rule
    public final ExpectedException exception = ExpectedException.none();

    @Before
    public void init(){
       MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getObjTest() throws Exception {
       // Arrange
       Path path = new Path("xyz://aa-bb-cc/data7-1-23-a.txt");

        doReturn(Mockito.anyString()).when(clientSpy)
           .pathToKey(Mockito.anyString(), Mockito.anyString());         

        when(memoryCache.getFileStatus(path.toString()))
           .thenReturn(fileStatus);

        when(fileStatus.isDirectory()).thenReturn(true);

        exception.expect(FileNotFoundException.class);

        // Act
        clientSpy.getObj(name, path);
    }
}

答案 1 :(得分:1)

方法getObj必须在一个类中声明(我们无法在OP中看到),但让我们假设它在这个类中:

public class Foo {
    private MemoryCache memoryCache;

    public Foo(MemoryCache memoryCache) {
        this.memoryCache = memoryCache;
    }

    public FSDataInputStream getObj(String hName, Path p) throws IOException {
        // ...
    }
} 

现在,您的测试可能如下所示:

public class ClientTest {
    private MemoryCache memoryCache = mock(MemoryCache.class);
    private FileStatus fileStatus = mock(FileStatus.class);

    @Rule
    public final ExpectedException exception = ExpectedException.none();

    @Test
    public void getObjTest() throws Exception {
        Path path = new Path("xyz://aa-bb-cc/data7-1-23-a.txt");

        // create the class-under-test, supplying the mocked MemoryCache
        Foo foo = new Foo(memoryCache);

        // establish your expectations on the mocked classes
        // for this test the expectations are:
        // - memoryCache returns the mocked fileStatus    
        // - the mocked fileStatus 'is a' directory        
        when(memoryCache.getFileStatus(path.toString())).thenReturn(fileStatus);
        when(fileStatus.isDirectory()).thenReturn(true);

        // you expect a FileNotFoundExceptionException ...
        exception.expect(FileNotFoundException.class);

        // ... when you invoke getObj
        foo.getObj("aString", path);
    }
}

注意:

  • 您必须在测试中调用getObj
  • getObj调用必须输入if (status.isDirectory()) { ... }
  • 你必须指示被模拟的MemoryCache返回被模拟的FileStatus
  • 在调用FileStatus时,您必须指示被模拟的isDirectory返回true
  • 您必须将模拟的MemoryCache提供给正在测试的Foo实例,在上面的示例中,这是通过构造函数注入完成的