我试图熟悉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)
有人可以告诉我做错了吗?
答案 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
实例,在上面的示例中,这是通过构造函数注入完成的