模拟Mockito 2的最后一堂课

时间:2016-12-05 16:57:40

标签: java unit-testing mockito

我正在从我正在进行的项目中移除Powermock,所以我试图仅使用Mockito(mockito-core-2.2.28)重写一些现有的单一测试。

当我运行测试时,出现以下错误:

  

org.mockito.exceptions.base.MockitoException:

     

无法模拟/间谍类com.ExternalpackagePath.Externalclass

     

Mockito不能嘲笑/间谍,因为:

     
      
  • 最后一堂课
  •   

我知道这个问题已被提出(How to mock a final class with mockitoMock objects calling final classes static methods with Mockito),但我找不到我正在寻找的答案。

以下是我的代码摘录:

public class MyClassToTest extends TestCase {
    private MyClass myClass;
    @Mock private Externalclass ext;  // This class is final, I would like to mock it

    @Override
    protected void setUp() throws Exception {
        MockitoAnnotations.initMocks(this); // <<<< The exception is thrown here
        ext = Mockito.mock(Externalclass.class);
    }
}

正如Mockito文档中提到的那样(https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2,§Mockthe unmockable),我添加了org.mockito.plugins.MockMaker文件。这是我项目的树:

  • 项目
    • SRC
      • com.packagePath.myPackage
        • myClass的
    • 测试
      • com.packagePath.myPackage
        • myClassToTest
      • 资源
        • 的Mockito的扩展
          • org.mockito.plugins.MockMaker

我还尝试将“resources”目录放在“src”中,在一个名为“test”的子目录中,但结果仍然相同。

我认为用Mockito v2嘲笑决赛是可能的。有人知道这里缺少什么吗?

谢谢!

7 个答案:

答案 0 :(得分:23)

很奇怪你的解决方案似乎有用。
根据他们在Github上的文件,它说。

  

最终类和方法的模拟是一种孵化,选择加入的功能。它使用Java代理程序检测和子类化的组合,以实现这些类型的可模拟性。由于这与我们当前的机制不同,并且这个机制具有不同的限制,并且由于我们希望收集经验和用户反馈,因此必须明确激活此功能以使其可用;它可以通过mockito扩展机制通过创建包含单行的文件src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker来完成:

mock-maker-inline
     

创建此文件后,Mockito将自动使用此新引擎,可以执行以下操作:

 final class FinalClass {
   final String finalMethod() { return "something"; }
 }

 FinalClass concrete = new FinalClass(); 

 FinalClass mock = mock(FinalClass.class);
 given(mock.finalMethod()).willReturn("not anymore");

 assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
     

在随后的里程碑中,团队将采用编程方式使用此功能。我们将为所有不可挽救的场景确定并提供支持。请继续关注,请告诉我们您对此功能的看法!

我的工作结构现在看起来像这样。

enter image description here

答案 1 :(得分:15)

我也无法使用配置文件;但是,Mockito团队非常友好,还提供了预配置的Mockito工件,无需在目标项目中进行配置。

因此,如果您使用Gradle并想要测试您的Kotlin代码,只需将其添加到项目的依赖项中:

testCompile 'org.mockito:mockito-inline:2.8.9'
testCompile('com.nhaarman:mockito-kotlin:1.5.0') {
    exclude group: 'org.jetbrains.kotlin'
    exclude group: 'org.mockito'
}

答案 2 :(得分:8)

嗯,我发现这里有什么问题,对其他人来说可能有用。我的项目树是错误的,我把org.mockito.plugins.MockMaker放在一个目录&#34; mockito-extension&#34;直接在&#34; src&#34;。这是我的树现在:

  • ·PROJET
    • SRC
      • com.packagePath.myPackage
        • myClass
      • 的Mockito的扩展
        • org.mockito.plugins.MockMaker
  • 测试
    • com.packagePath.myPackage
      • myClassToTest

答案 3 :(得分:2)

您似乎遇到了类路径问题,就像我一样。

您之前的设置也有效,但似乎

project/test/resources

不在您的类路径中。

当我尝试使用IntelliJ运行时,我遇到了同样的问题。我只是将资源目录标记为测试资源根,它工作正常。赞美Mockito的众神!

答案 4 :(得分:0)

此解决方案对我有用: 而不是

testCompile "org.mockito:mockito-android:2.9.0"
在gradle文件中

,将其替换为

testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.9.0' 

它会起作用。

答案 5 :(得分:0)

我遇到了与您描述的问题相同的问题。对我来说,解决方案是在org.mockito.plugin.MockMacker目录中创建/test/java/resources/mockito-extensions/文件并编写以下行:mock-maker-inline

因此,MockMaker实际上是文件扩展名(无需txt,属性或任何其他扩展名)。

答案 6 :(得分:0)

如果项目中有多个模块,请检查它们是否也有对Mockito的引用。对我来说,这个问题在其他一些小型且被遗忘的库模块中已被弃用和不必要的定义:

testCompile 'org.mockito:mockito-all:1.10.19'

删除此不必要的声明为我解决了问题