简体   繁体   中英

How to unit-test a presenter in a MVP

I have a model view presenter triad. I'd like to know what's the usual way to test the presenter.

The first thing that came to my mind was to instantiate the presenter and instantiate a real view and then assert that the view would accomplish the expected behavior.

public void itShouldSayHello() {
    View view = new View();
    Presenter presenter = new Presenter(view);
    presenter.userSaid("hello");
    assertTrue(view.getGreeting().equals("hello"));
}

Then I thought that the view was not under test and so I created a fake view.

private String greeting;

public void itShouldSayHello() {
    View view = new FakeView();
    Presenter presenter = new Presenter(view);
    presenter.userSaid("hello");
    assertTrue(greeting.equals("hello"));
}
private class FakeView implements View {
    @Override
    public void displayGreeting(String saluto) {
        greeting = saluto;
    }
}

Then I thought that the interface of the view could change. This would've made the code harder to maintain. So I wrote the test and asserted that something was to be presented to the view. This way even if the interface changed I would have to change one line of code in the tests.

public void itShouldSayHello() {
    View view = mock(View.class);
    Presenter presenter = new Presenter(view);
    presenter.userSaid("hello");
    verify(view).displayGreeting("hello");
}

So basically what I test now is that I expect the presenter to gather and process some information and finally pass it to the view, then I verify that the passed values are correct.

So I guess I'm not using a fake now, I'm using a mock and then I verify if the mock receives the correct values.

Another problem I have is with the model. But I think this is insurmountable. What I have to do to see if the presenter behaves correctly is to create a big fat fixture. Then a pass all the various combinations and see if the presenter behaves correctly.

How do you test your presenter?

You leverage the separation of view/presenter to test the presenter. If you've implemented MVP fully, your View will implement an interface and your Presenter will use that interface to return data to the View. If you are testing your MVP application you will want not just your Presenter to function correctly, but also the interface the View uses to communicate with the Presenter.

So your test class should implement the View's interface, invoke methods of the Presenter, and store responses from the Presenter from the local methods that override the interface. If your Presenter communicates with the business layer synchronously, this is easier:

  1. Define a test class that implements the View interface
  2. Implement the interface in the test class so data prepared by the presenter is stored in the test object
  3. Create test methods in the test class that invoke the presenter, get the response from the object, and perform the appropriate comparisons.

If your Presenter communicates asynchronously you will have to do something like wait in the test method and notify from the interface methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM