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

fgy*_*ica 14 android bouncycastle mockito robolectric

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

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

Security.insertProviderAt(new BouncyCastleProvider(), 1);
Run Code Online (Sandbox Code Playgroud)

现在,这些测试在自己运行运行得非常好 - 例如,当我直接从测试类中运行单个方法,或者从Project树菜单中运行这些类时,它们工作得很好.

但是,当我运行沿着所述侧测试ANY它使用测试RobolectricTestRunner(例如,如果我只是犯前一起运行在我的项目的所有测试),我得到以下异常:

java.io.IOException: error constructing MAC:
java.lang.SecurityException: JCE cannot authenticate the provider BC
Run Code Online (Sandbox Code Playgroud)

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


附加信息:

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

小智 1

看起来 Robolectric正在使用自己的类加载器(这有利于 Android API 上的替代品),这可能与 Mockito 的常规类加载器发生冲突。

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

  1. 利用 Robolectric 跑步机。Robolectric 使用自己的类加载器,有利于替代 Android API,因此它确实需要自己处理类加载。没有其他方法可以使用 Robolecric。

  2. 将 @RunWith(MockitoJUnitRunner.class) 替换为覆盖 MockitoJUnitRunner 行为的替代方法:

    @Before public void setUpMockito() {
       MockitoAnnotations.initMocks(this);
     }
    
     @After public void tearDownMockito() {
       Mockito.validateMockitoUsage();
     }
    
    Run Code Online (Sandbox Code Playgroud)

也许这可能是同时使用 Robolectric 类加载器和 Mockito 的解决方法。