Gustik
Gustik

Reputation: 323

How to verify to call or not to call a method

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

  });

}

I want to make sure when presenter.loadContacts() is called from the code, then verify view.onLoadContactsComplete is called also but getting an error:

Used on a non-mockito object

Is there a possibility to do this with Mockito?

Update:

abstract class ContactListViewContract {
  void onLoadContactsComplete(List<Contact> items);
  void onLoadContactsError();
}

here the onLoadContactsComplete method is called

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

}

Mocked Repository. Fetch mocked data.

class MockContactRepository implements ContactRepository{

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

}

Upvotes: 18

Views: 19502

Answers (3)

Victor Lagunas
Victor Lagunas

Reputation: 193

You can use never and verifyZeroInteractions

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

*mark verifyZeroInteractions as deprecated in mockito-kotlin, too introduce an alias for verifyNoInteractions

Upvotes: -2

Raheel Riaz
Raheel Riaz

Reputation: 251

Mockito provides native support for both

  1. To test that your method has been called at least once you can use verify(<your-method-with-expected-params>) this will verify that your method has called (no matter how many times). To verify that it has been called for a specific number of times you can chain it with .called(<number-of-calls-expected>)

  2. To test that your method hasn't been called you should use verifyNever(<your-method-with-expected-params>) this will validate that your method hasn't been invoked

Make sure that the method passed to both verify and verifyNever are the methods which have been Mocked by Mockito.

Upvotes: 1

Nkosi
Nkosi

Reputation: 247123

when calling verify method you need call the actual method on the mock

Try

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

});

If the method was not called once, the test will fail.

Upvotes: 19

Related Questions