如何验证是否调用了一个方法

18
class MockView extends Mock implements ContactListViewContract {

  @override
  void onLoadContactsComplete(List<Contact> items) {

  }
  @override
  void onLoadContactsError() {}

}

void main() {

  test('ContactListPresenter test', () {
    Injector.configure(Flavor.MOCK);
    MockView view = new MockView();

    ContactListPresenter presenter = new ContactListPresenter(view);

    presenter.loadContacts();

    verify(view.onLoadContactsComplete).called(1);

  });

}
我希望确保当从代码中调用 presenter.loadContacts() 时,验证也会调用 view.onLoadContactsComplete,但是出现错误:

在非mockito对象上使用

有没有可能使用Mockito解决这个问题?
更新:
abstract class ContactListViewContract {
  void onLoadContactsComplete(List<Contact> items);
  void onLoadContactsError();
}

这里调用了onLoadContactsComplete方法。

class ContactListPresenter {
  ContactListViewContract _view;
  ContactRepository _repository;

  ContactListPresenter(this._view){
    _repository = new Injector().contactRepository;
  }

  void loadContacts(){
    assert(_view != null);

    _repository.fetch()
        .then((contacts) {
          print(contacts);
          _view.onLoadContactsComplete(contacts); // here the onLoadContactsComplete method is called
        }).catchError((onError) {
          print(onError);
          _view.onLoadContactsError();
        });
  }

}

模拟仓库。获取模拟数据。

class MockContactRepository implements ContactRepository{

  Future<List<Contact>> fetch(){
    return new Future.value(kContacts);
  }

}
3个回答

19

在调用verify方法时,您需要在模拟对象上调用实际的方法。

尝试一下

test('ContactListPresenter test', () async {
    Injector.configure(Flavor.MOCK);
    MockView view = new MockView();

    ContactListPresenter presenter = new ContactListPresenter(view);

    presenter.loadContacts();

    await untilCalled(view.onLoadContactsComplete(typed(any))); 
    //completes when view.onLoadContactsComplete(any) is called

    verify(view.onLoadContactsComplete(typed(any))).called(1);

});
如果方法未被调用一次,测试将失败。

1
可能是因为在Future中调用了方法(onLoadContactsComplete)? - Gustik
1
我尝试了 verify(view.onLoadContactsComplete(kContacts)).called(1); 但是得到了相同的错误: Used on a non-mockito object . 方法 onLoadContactsComplete 被100%调用。 - Gustik
1
我遇到了在非Mockito对象上使用的错误,因为模拟视图实现了抽象ContactListViewContract。我创建了一个新类来实现ContactListViewContract并已经对其进行了模拟,并尝试了您提供的异步选项 - 一切都正常工作!谢谢! - Gustik
“untilCalled”和“verify”之间有什么区别?我的意思是,如果untilCalled(view.onLoadContactsComplete(typed(any)))成功了,那么verify(view.onLoadContactsComplete(typed(any))).called(1)不就没用了吗?它只是再次检查该方法是否被调用。 - Little Monkey

1

Mockito提供了本地支持来进行以下两种测试:

  1. 要测试方法是否已被调用至少一次,您可以使用verify(<your-method-with-expected-params>),这将验证该方法是否已被调用(无论调用次数如何)。要验证它已被调用特定次数,您可以将其链接到.called(<number-of-calls-expected>)

  2. 要测试方法未被调用,应使用verifyNever(<your-method-with-expected-params>),这将验证该方法未被调用

确保传递给verifyverifyNever的方法是由Mockito模拟的方法。


-2

你可以使用 neververifyZeroInteractions

//interaction with mockOne
    mockOne.add("one");
     
    //ordinary interaction 
    verify(mockOne).add("one");
     
    //we never interaction into the mock 
    verify(mockOne, never()).add("two");
     
    //verify we don't use in the mock 
    verifyZeroInteractions(mockTwo, mockThree);

在mockito-kotlin中,将verifyZeroInteractions标记为已弃用,并引入verifyNoInteractions的别名。

1
这是个谎言。你确定这是 Dart 代码吗?当我添加这段代码时,它会抛出异常,说“函数 'never' 未定义”。 - Yonko Kilasi

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