如何在Mockito中验证调用了一个方法内部的方法

4

我正在使用mockito进行Flutter的单元测试,但是我感觉无法验证一个方法是否在另一个方法中被调用。到目前为止,我编写的代码如下:

我想要测试的类

class A {
  void doSomething() {
    callMe();
  }

  void callMe() {}
}

模拟类

class MockA extends Mock implements A {}

我写的测试,

test("Test method is called", () {
    A a = new MockA();
    a.doSomething();
    verify(a.callMe()).called(1);
  });

当我运行上述测试时,出现了一个错误

No matching calls. All calls: MockA.doSomething()
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)

如果我验证 doSomething 被调用它可以工作,但是在 doSomething 中对 callMe 的调用不起作用。这是默认行为还是我做错了什么?请注意,我需要验证 doSomething() 被调用时是否调用了 callMe() 方法。

1个回答

5

您使用MockA来替换A并进行了模拟。Mocks没有实现,MockA.doSomething() 什么也不做,也不能调用MockA.callMe()

A.doSomething() 调用A.callMe()应该被视为doSomething()的具体实现细节; 让测试依赖于此将会紧密地耦合测试和特定的实现,并且非常容易出错。

您不能使用mock来验证正在被mock的对象的实现。如果要验证A.doSomething()的实现,则应使用实际对象并验证该对象的可观察属性。

但如果您真的想这样做,那么您需要修改A以不调用自身方法,而是调用一个提供的对象上的方法(即“依赖注入”)。例如:

class A {
  final late A a;

  A({A? a}) {
    this.a = a ?? this;
  }

  void doSomething() {
    a.callMe();
  }

  void callMe() {}
}

test("Test method is called", () {
    var mockA = MockA();
    var actualA = A(a: mockA);
    actualA.doSomething();
    verify(mockA.callMe()).called(1);
  });

一个类依赖于自己的模拟对象有点不寻常,如果你想要验证callMe()调用是否正确,这种方法也无法扩展。

另一种更可扩展的方法(但需要更多工作)是创建自己的虚假类来跟踪方法调用:

class TrackedA implements A {
  int doSomethingCallCount = 0;
  int callMeCallCount = 0;

  @override
  void doSomething() {
    doSomethingCallCount += 1;
    super.doSomething();
  }

  @override
  void callMe() {
    callMeCallCount += 1;
    super.callMe();
  }
}

但是,这种方法非常脆弱,我不建议使用。


感谢您详细的回答,现在我明白了。 - SVG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接