0

While using MVP pattern for WinForms I come across scenarios where I call some private methods in my public method of Presenter and change a few properties of the View.

How can I unit test these situations efficiently?

public void OnFileNameChanged(string fileName)
{
    _settings = FirstPrivateOperation()

    if (_settings == null)
    {
        _view.A = false;
        return;
    }

    var config = SecondPrivateOperation();

    if (config == null)
    {
        _view.B = true;
        return;
    }

    _view.C = true;
}
Stefan
  • 648
  • 5
  • 18
Vahid
  • 4,369
  • 10
  • 55
  • 116
  • Possible duplicate of [Unit testing private methods in C#](https://stackoverflow.com/questions/9122708/unit-testing-private-methods-in-c-sharp) – Andrei Dragotoniu Sep 20 '19 at 08:01
  • @AndreiDragotoniu Thanks Andrei, I read the answers for that. It has two main answers with opposite recommendations. I am still not sure what to do. – Vahid Sep 20 '19 at 08:05
  • In essence you test this public method by the result it provides. If you look at it as a black box it wil either set `_view.A = false`, `_view.B = true` and/or `_view.C = true`. Is it possible to review these conditions to validate that this method works? – Stefan Sep 20 '19 at 09:34
  • Just being curious: Why is `filename` not used in your example? – Stefan Sep 20 '19 at 09:38
  • @Stefan In actual code, it is used by one of the methods. Here I changed the method names to show they are private :p – Vahid Sep 20 '19 at 11:24
  • @Stefan Yes, it is possible. I just want to know if this is the way to go. Since it is is Presenter, my public methods will have side effects (changing the View), so I do not think I can change the private methods to pure codes. – Vahid Sep 20 '19 at 11:26
  • 1
    @Vahid I would try that and see if it results in a reliable unit test – Stefan Sep 20 '19 at 12:10

1 Answers1

1

Some options, based on what you showed, would be :

  1. mock the two methods which set these values,
  2. break _settings and config or even the two methods which provide the results into a separate class ( like a configuration kind of thing ) and inject the interface of that class as a dependency at whatever level it makes sense. You can then mock those values.

I would pursue one of these options.

In regards to the View values, I would try to separate that. There are number of issues with this code.

  1. you have a OnFileNameChanged metho and you probably can't change its signature and doesn't return anything. So, I would separate the code even more. Take the code out of it and create another method that you control. Do not add any View setting in that one. The purpose ifs to cover the logic and return an object with some calculated values. Then, in the OnFileNameChanged you assign what you need for the view stuff. In short, take the logic part out and deal with it somewhere else and test that.

You have 3 values that you are assigning to the View object, so make your new method return either one value, or an object with three values, covering each possibility.

public void OnFileNameChanged(string fileName)
{
   var calculatedValues = CalculateValues(//might need some params here)

   _view.A = calculatedValues.A;
   _view.B = calculatedValues.B;
   _view.C = calculatedValues.C;
}

public MyReturnType CalculateValues()
{
     var result = new MyReturnType();
     var config = FirstPrivateOperation();
     if ( config == null ) { return result; }

     //etc etc
}

public MyReturnType
{  
      public Whatever A { get;set }
      public Whatever B { get;set }
      public Whatever C { get;set }
}

you can go even further and deal with the private methods in a different way. you might want to add a separate class to replace them and then that makes theme easier to test / mock as well.

Andrei Dragotoniu
  • 5,633
  • 3
  • 16
  • 30
  • What about setting the values to View? How should test these? For example let's say I am testing the part where _settings is null. What should I put under test? Should_ReturnAndSetSomeValuesToView_WhenSettingIsNull() ? – Vahid Sep 20 '19 at 08:22