在莫基托中加载模拟类



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

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

我可以这样做吗?

它永远不可能是A类以外的任何东西

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

Mockito通过子类

工作:由mock(Foo.class)@Mock Foo mockFoo创建的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 无法通过多态性自行调整。

就我个人而言,我非常喜欢解决方案1:代码由您控制,只要您清楚您的测试是被测系统的一流消费者,您就可以自由地将其设计为可测试。

通过构造函数来做是我更喜欢的。

例如

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);
      }
 }

使用 Mockito 执行此操作非常简单。

public class Foo {
     private ClassA classA;
}

测试将如下所示:

@RunWith(MockitoJUnitRunner.class)
public class FooTest {
  @Mock
  private ClassA classA;
  @InjectMocks
  private Foo foo = new Foo();
  //Test methods
}

就是这样,你嘲笑了A级!

相关内容

  • 没有找到相关文章

最新更新