我是mockito测试的新手,我一直在努力关注博客,但现在很混乱。
座右铭是测试FileUtility
类中的两个静态函数。代码如下。
public static boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
public static String getLogFilePath(String fileName) {
if (isExternalStorageWritable()) {
File _file;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
_file = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS);
if (exists(_file)) {
return getAbsoluteFilePath(_file,fileName);
}
}
_file = Environment.getExternalStorageDirectory();
if (exists(_file)) {
return getAbsoluteFilePath(_file,fileName);
}
}
File _file = Environment.getDataDirectory();
if (exists(_file)) {
return getAbsoluteFilePath(_file,fileName);
}
return fileName;
}
private static boolean exists(File file) {
return file != null && file.exists();
}
我应该如何编写单元测试用例来测试该函数的输入,如"fileName=null"?
请分享一些光/代码。
看起来有三条主要路径通过getLogFilePath()
:
- 如果外部存储是可写的,并且外部存储公用目录可用,则使用它
- 如果外部存储是可写的,并且外部存储公用目录不可用,但外部存储目录可用,则使用它
- 在所有其他情况下,使用数据目录
编写这些测试用例只涉及对以下方法的一些模拟期望:
Environment.getExternalStorageState()
Environment.getExternalStoragePublicDirectory()
Environment.getExternalStorageDirectory()
Environment.getDataDirectory()
这里有一个例子:
// this test case need to mock static methods so it uses PowerMock
@RunWith(PowerMockRunner.class)
// this static methods to be mocked are on Environment so that must be 'prepared'
@PrepareForTest({Environment.class})
public class StorageUtilsTest {
@Rule
public TemporaryFolder storageDirectory = new TemporaryFolder();
private File nonExistentDirectory;
private File existentDirectory;
@Before
public void setup() {
nonExistentDirectory = Mockito.mock(File.class);
Mockito.when(nonExistentDirectory.exists()).thenReturn(false);
existentDirectory = storageDirectory.getRoot();
PowerMockito.mockStatic(Environment.class);
}
@Test
public void willUseTheExternalStoragePublicDirectoryWhenItIsAvailable() {
// external storage is writeable
Mockito.when(Environment.getExternalStorageState()).thenReturn(Environment.MEDIA_MOUNTED);
// the external storage public directory is available
Mockito.when(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)).thenReturn(existentDirectory);
String fileName = "someFileName";
String logFilePath = StorageUtils.getLogFilePath(fileName);
Assert.assertEquals(existentDirectory.getAbsolutePath() + File.separator + fileName, logFilePath);
}
@Test
public void willUseTheExternalStorageDirectoryWhenItIsAvailable() {
// external storage is writeable
Mockito.when(Environment.getExternalStorageState()).thenReturn(Environment.MEDIA_MOUNTED);
// the external storage public directory is not available
Mockito.when(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)).thenReturn(nonExistentDirectory);
// the external storage directory is available
Mockito.when(Environment.getExternalStorageDirectory()).thenReturn(existentDirectory);
String fileName = "someFileName";
String logFilePath = StorageUtils.getLogFilePath(fileName);
Assert.assertEquals(existentDirectory.getAbsolutePath() + File.separator + fileName, logFilePath);
}
@Test
public void willUseTheDataDirectoryWhenExternalStorageIsNotWriteable() {
// external storage is not writeable
Mockito.when(Environment.getExternalStorageState()).thenReturn("not media mounted");
// the data directory is available
Mockito.when(Environment.getDataDirectory()).thenReturn(existentDirectory);
String fileName = "someFileName";
String logFilePath = StorageUtils.getLogFilePath(fileName);
Assert.assertEquals(existentDirectory.getAbsolutePath() + File.separator + fileName, logFilePath);
}
@Test
public void willUseTheDataDirectoryWhenNothingElseIsAvailable() {
// external storage is writeable
Mockito.when(Environment.getExternalStorageState()).thenReturn(Environment.MEDIA_MOUNTED);
// but neither of the external storage directories are available
Mockito.when(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)).thenReturn(nonExistentDirectory);
Mockito.when(Environment.getExternalStorageDirectory()).thenReturn(nonExistentDirectory);
// so we must fall through to the data directory
Mockito.when(Environment.getDataDirectory()).thenReturn(existentDirectory);
String fileName = "someFileName";
String logFilePath = StorageUtils.getLogFilePath(fileName);
Assert.assertEquals(existentDirectory.getAbsolutePath() + File.separator + fileName, logFilePath);
}
@Test
public void doesSomethingWhenGivenANullFileName() {
// external storage is writeable
Mockito.when(Environment.getExternalStorageState()).thenReturn(Environment.MEDIA_MOUNTED);
// the external storage public directory is available
Mockito.when(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)).thenReturn(existentDirectory);
String logFilePath = StorageUtils.getLogFilePath(null);
// the assertion here will depend on what your getAbsoluteFilePath() method does with a null file name!
Assert.assertEquals(existentDirectory.getAbsolutePath() + File.separator, logFilePath);
}
}
注:
- 这使用JUnit TemporaryFolder规则为断言创建(并在完成时丢弃)一个目录。这也可以使用模拟的
File
实例来实现 OP没有包含
getAbsoluteFilePath()
的定义,所以我推测它是这样的:private static String getAbsoluteFilePath(File file, String fileName) { return file.getAbsolutePath() + File.separator + fileName; }
- 上面的例子并非详尽无遗,它旨在提供足够的,以便您了解它是如何工作的以及如何测试静态方法等