Mockito中的SecurityProvider与Robolectric一起运行时进行测试

时间:2017-04-06 14:28:35

标签: android mockito bouncycastle robolectric

我们有一个Android项目,我们使用MockitoTestRunner和RobolectricTestRunner进行不同类型的测试。

我编写了一组与SSL有关的单元测试,因此加载了证书/密钥库/信任库等。为此,我使用MockitoJUnitRunner并以编程方式添加了Bouncycastle提供程序:

Security.insertProviderAt(new BouncyCastleProvider(), 1);

现在,这些测试运行完全正常 在自己运行时 - 例如当我直接从测试类中运行单个方法,或者从项目树菜单中运行这些类时,它们的工作正常。

但是当我在使用RobolectricTestRunner ANY 测试中运行所述测试时(例如,如果我之前在我的项目中一起运行所有测试)提交),我得到以下异常:

java.io.IOException: error constructing MAC:
java.lang.SecurityException: JCE cannot authenticate the provider BC

我感到困惑。一个测试类中使用的testrunner将如何影响其他类的运行,特别是如果我们使用不同的测试运行器?

其他信息:

  • 只有在我实际尝试对BC提供程序执行某些操作时才会出现异常(例如,第一次测试尝试加载PKCS12证书) - insertProviderAt(...)调用本身似乎正常通过......
  • 另外,当我打印出每个测试运行的提供程序列表时,我看到Robolectric已经有一个BC提供程序,但是当我尝试使用它时仍然失败。
  • 此外,如果我添加BC提供程序,则在与Robolectric测试一起在测试套件中运行时,测试仍然会失败并出现相同的错误。单独运行时,由于我们明确指定了提供程序,因此java.security.NoSuchProviderException: no such provider: BC失败。

1 个答案:

答案 0 :(得分:1)

好像Robolectric is using its own classloader(支持在Android API上进行替换),可能与Mockito的常规类加载器冲突。

因此,要同时使用Robolectric和Mockito,可以执行以下操作:

  1. 使用Robolectric流道。 Robolectric使用自己的类加载器,该类加载器支持替换Android API,因此它确实需要自行处理类加载。没有其他方法可以使用Robolecric。

  2. 使用覆盖MockitoJUnitRunner行为的以下替代方法替换@RunWith(MockitoJUnitRunner.class):

    @Before public void setUpMockito() {
       MockitoAnnotations.initMocks(this);
     }
    
     @After public void tearDownMockito() {
       Mockito.validateMockitoUsage();
     }
    

也许同时使用Robolectric类加载器和Mockito是一种解决方法。