Search code examples
javaunit-testingmvp

How to unit test a presenter that spawns another view without a GUI appearing?


I have a presenter class that will spawn a new presenter and view upon successful execution. Prior to spawning the next presenter/view, some business logic executes that I wish to unit test. My issue is that I cannot avoid an actual GUI window appearing when my unit test executes.

Here is some psuedo-code that demonstrates the issue:

// View1 and Model are interfaces
public Presenter1(View1 view, Model model) {
  // ....
}


public void handleOKClick() {
  // Method triggered by view

  String data = view.getSomeUserInput();
  // ... business logic I wish to test  


  if (shouldLoadNextView) {
    // Business logic concluded the next view should be loaded

    View2 nextView = new View2Impl();
    Presenter2 nextPresenter = new Presenter2(nextView, model);
    nextView.setPresenter(nextPresenter);
    nextView.showView();
  }
}

In my unit test, I can mock the View1 and Model instances that I pass to my Presenter1 constructor. I can then check that my business logic interacts with these as expected. What I can't currently do is prevent the next view from displaying, as my Presenter1 instance will construct a concrete implementation of View2 and display it.

I feel like I'm left with three choices:

  1. Change the design of my class. Perhaps the Presenter1 constructor should take a View2 instance as an argument, allowing me to mock it for the purposes of testing.

  2. Find a cunning way to kill the view from my unit test code, once it has appeared. I'm not sure how best to do this.

  3. Make a more fundamental change to my project class design so that presenters never spawn new views in this fashion.


Solution

  • Time has passed and I've since adopted option 1. It feels clunky to pre-construct views when they may not be needed, but equally my view classes are lightweight and cheap to construct.