2017-10-05 134 views
0

我是新来mockito测试,我一直在试图跟随博客,但它现在非常混乱。Mockito的环境getExternalStorageState()android

座右铭是测试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”的函数?

请分享一些光/代码到它。

+0

你不能用mockito测试静态函数。尝试使用PowerMock –

回答

1

看起来主要有三种路径通过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); 
    } 
} 

注:

  • 这使用TemporaryFolder规则以创建(并丢弃在完成)的断言目录JUnit的。这也可以使用模拟的File实例来实现。
  • 的OP没有包括getAbsoluteFilePath()的定义,所以我认为它是这样的:

    private static String getAbsoluteFilePath(File file, String fileName) { 
        return file.getAbsolutePath() + File.separator + fileName; 
    } 
    
  • 上面的例子并不旨在穷尽,它旨在提供刚够使你可以理解它是如何工作的以及如何测试静态方法等
+0

我希望我能给你更多的星星或什么,而不是upvote。答案非常有效。我在测试时做了一些改变,从你的解释中得知 – Vansi