Kon*_*rdź 2 java testing unit-testing mockito writer
这是我在某个服务类中的方法。它是公开的,因此应该进行测试。我只是不知道我应该测试什么。我会模拟Writer和 spyOn 函数调用,但是使用这种实现是不可能的(不是吗?)
我正在使用Mockito和JUnit
现在,我只能使函数抛出和断言该异常
有什么帮助吗?
@Override
public void initIndexFile(File emptyIndexFile) {
try {
Writer writer = new FileWriter(emptyIndexFile);
writer.write("[]");
writer.close();
} catch (IOException e) {
throw new IndexFileInitializationException(
"Error initialization index file " + emptyIndexFile.getPath()
);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您觉得添加特殊内容是业务逻辑,因此是您的类的责任,那么创建 FileWriter 就不是(根据单一责任模式.
因此,您应该使用在 Test 下FileWriterFactory注入到您的Class 中的。然后你可以模拟它FileWriterFactory以返回Writer接口的模拟实现,然后你可以检查它是否获得了预期的字符串。
您的 CuT 将更改为:
private final WriterFactory writerFactory;
public ClassUnderTest(@Inject WriterFactory writerFactory){
this.writerFactory = writerFactory;
}
@Override
public void initIndexFile(File emptyIndexFile) {
try {
Writer writer = writerFactory.create(emptyIndexFile);
writer.write("[]");
writer.close();
} catch (IOException e) {
throw new IndexFileInitializationException(
"Error initialization index file " + emptyIndexFile.getPath()
);
}
}
Run Code Online (Sandbox Code Playgroud)
以及您对此的测试:
class Test{
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private FileWriterFactory fileWriterFactory;
private Writer fileWriter = spy(new StringWriter());
File anyValidFile = new File(".");
@Test
public void initIndexFile_validFile_addsEmptyraces(){
//arrange
doReturn(fileWriter).when(fileWriterFactory).create(any(File.class));
// act
new ClassUnderTest(fileWriterFactory).initIndexFile(anyValidFile);
//assert
verify(fileWriterFactory)create(anyValidFile);
assertEquals("text written to File", "[]", fileWriter.toString());
verify(fileWriter).close();
}
}
Run Code Online (Sandbox Code Playgroud)
此外,您可以轻松检查您的 CuT 是否拦截了 IOException:
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void initIndexFile_missingFile_IndexFileInitializationException(){
//arrange
doReturnThrow(new IOException("UnitTest")).when(fileWriterFactory).create(any(File.class));
//assert
exception.expect(IndexFileInitializationException.class);
exception.expectMessage("Error initialization index file "+anyValidFile.getPath());
// act
new ClassUnderTest(fileWriterFactory).initIndexFile(anyValidFile);
}
Run Code Online (Sandbox Code Playgroud)
好的!一个工厂只是为了测试 3 行代码!– 尼古拉斯·菲洛托
这是个好的观点。
问题是:该类中是否有任何方法File直接与对象交互并需要在之后创建 FileWriter?
如果遵循 KISS 原则的答案是“否”(因为它最有可能),您应该Writer直接注入一个对象而不是工厂,并且您的方法没有 File 参数。
private final Writer writer;
public ClassUnderTest(@Inject Writer writer){
this.writer = writer;
}
@Override
public void initIndexFile() {
try {
writer.write("[]");
writer.close();
} catch (IOException e) {
throw new IndexFileInitializationException(
"Error initialization index file " + emptyIndexFile.getPath()
);
}
}
Run Code Online (Sandbox Code Playgroud)
修改测试:
class Test{
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Rule public ExpectedException exception = ExpectedException.none();
@Mock
private FileWriterFactory fileWriterFactory;
@Mock
private Writer failingFileWriter;
private Writer validFileWriter = spy(new StringWriter());
File anyValidFile = new File(".");
@Test
public void initIndexFile_validFile_addsEmptyraces(){
//arrange
// act
new ClassUnderTest(validFileWriter).initIndexFile();
//assert
verify(fileWriterFactory)create(anyValidFile);
assertEquals("text written to File", "[]", fileWriter.toString());
verify(fileWriter).close();
}
@Test
public void initIndexFile_missingFile_IndexFileInitializationException(){
//arrange
doReturnThrow(new IOException("UnitTest")).when(failingFileWriter).write(anyString());
//assert
exception.expect(IndexFileInitializationException.class);
exception.expectMessage("Error initialization index file "+anyValidFile.getPath());
// act
new ClassUnderTest(fileWriterFactory).initIndexFile(anyValidFile);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5591 次 |
| 最近记录: |