在Mockito中加载一个模拟类

时间:2016-04-25 22:23:59

标签: junit mockito

是否有一种简单的方法,使用Mockito,在请求另一个时加载模拟类或覆盖测试ClassLoader?

基本上我有一个Foo级,有一个成员" ClassA"在里面。我想替换使用" TestClassA"而不是" ClassA"在测试期间。我不想使用依赖注入,因为它对实际操作没有任何意义。 (它绝不可能是ClassA以外的任何东西)

我可以这样做吗?

3 个答案:

答案 0 :(得分:1)

  

它绝不可能是ClassA

以外的任何东西

...除了它,在你的测试中。测试代码是真正的代码,虽然这并不意味着它应该潜入您的生产应用程序,但它确实意味着您需要编写所有用例所需的灵活性和< em>包括测试。

Mockito通过子类工作:由mockFoomock(Foo.class)创建的@Mock Foo mockFoo实际上是Mockito创建的代理子类,它覆盖了Foo的每个方法。正如您从该描述中所知,Mockito因此无法更改每个 Foo对象的行为,尤其是无法更改从new Foo()返回的对象的类型。

我有两种选择,我可以看到:

  1. 接受其中一个构造函数中的ClassA或InterfaceA实例。如果将测试放在与测试类相同的Java包中(即使在不同的源代码树中),您甚至可以使构造函数包私有,或者将其保密,并创建一个静态工厂方法,如createForTest(ClassA)

    示例:

    public class ConsumerToTest {
      private final ClassA classA;
    
      /** For public use. */
      public ConsumerToTest() {
        this(new ClassA());
      }
    
      /** For use in tests. */
      ConsumerToTest(ClassA class) {
        this.classA = classA;
      }
    
      // ...
    }
    
  2. 使用PowerMock,其中包含名为PowerMockito的Mockito集成。虽然Mockito使用纯代理子类和代码生成,但PowerMockito实际上重写了被测系统的字节码。这意味着您可以模拟Mockito无法通过多态自行调整的静态方法和构造函数。

  3. 就个人而言,我非常喜欢解决方案1:代码是你自己控制的,只要你清楚你的测试是你测试系统的一流消费者,你就可以自由设计它首先是可测试的。

答案 1 :(得分:0)

通过构造函数执行它是我更喜欢的。

例如

public class Foo {
     private ClassA classA;

     public Foo(ClassA classA) {
         this.classA = classA;
     }
 }

public class FooTest {
     private Foo foo;

      @before
      public void setup() {
          foo = new Foo(Mockito.mock(ClassA.class);
      }
 }

答案 2 :(得分:0)

使用 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="4dp"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginRight="4dp" android:layout_weight="1"/> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="4dp" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="4dp"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginRight="4dp" android:layout_weight="1"/> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="4dp" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="4dp"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginRight="4dp" android:layout_weight="1"/> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="4dp" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="4dp"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginRight="4dp" android:layout_weight="1"/> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="4dp" android:layout_weight="1"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="4dp"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginRight="4dp" android:layout_weight="1"/> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="4dp" android:layout_weight="1"/> </LinearLayout> </LinearLayout> 执行此操作非常简单。

Mockito

测试将如下所示:

public class Foo {
     private ClassA classA;
}

就是这样,你嘲笑了ClassA!