Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

}
like image 472
Gustik Avatar asked Jan 17 '18 03:01

Gustik


People also ask

How do you know if a method is called?

If we want to verify that only one method is being called, then we can use only() with verify method.

Which annotation helps you to disable a test method?

Annotation Type Ignore. Sometimes you want to temporarily disable a test or a group of tests. Methods annotated with Test that are also annotated with @Ignore will not be executed as tests. Also, you can annotate a class containing test methods with @Ignore and none of the containing tests will be executed.


2 Answers

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.

like image 124
Nkosi Avatar answered Oct 15 '22 07:10

Nkosi


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.

like image 30
Raheel Riaz Avatar answered Oct 15 '22 05:10

Raheel Riaz