1

This is an existing C# .NET WinForms project. I assume it was not developed with unit tests in mind from the very beginning. It uses a Model-View-Controller architecture, and the backend is a content repository (a kind of heirarchical database) which I am not too familiar with, since I have only touched the front end.

I have been asked to create interfaces for each public class, including the forms. These will be used for unit testing with NUnit. This is complete. What is the best approach now? The only thing that comes to mind at the moment, is to create concrete classes from these interfaces, which is just re-implementing the existing classes in the application. Outside of the fact that this will make the unit tests "mind their own business", I don't see what the purpose of re-writing the classes is.

If this is the correct approach, it does not seem difficult to test things such as the Model, which contains an OOP representation of the database. How should the forms be tested?

7
  • Why would you rewrite the classes? If you are adding interfaces only then why not make those classes implement these new interfaces? Not sure if NUnit supports mocking classes like JUnit Mockito does, if it does re-consider adding interfaces for all the classes. Add only for those which need to be abstracted out and might have multiple implementations in future.
    – Nils
    Commented Mar 13, 2020 at 5:46
  • @Nils by "those" do you mean the original classes? They have all been made to implement these new interfaces. What I don't get is how to use the interfaces for unit testing.
    – Al2110
    Commented Mar 13, 2020 at 5:48
  • 2
    If Class A depends upon Class B which implements Interface IB, then Clas A will only depend on Interface IB at compile-time, whose implementation should be provided by some DI framework. So while testing class A now you can provide mock implementation of interface IB and not the class B.
    – Nils
    Commented Mar 13, 2020 at 5:51
  • @Nils oh I see. I think that makes it more clear. Thank you.
    – Al2110
    Commented Mar 13, 2020 at 5:59
  • 1
    Downvoters, the downvote button is for bad questions, not for bad ideas!
    – Doc Brown
    Commented Mar 13, 2020 at 6:56

1 Answer 1

2

If there are two classes A and B where A depends on B, and one wants to unit test A in isolation, the standard approach is to

  1. Create a public interface IB (and derive B from this interface).

  2. Make A depend only on IB instead of B directly (which involves reorganisation where instances of B are created and injected into A, maybe utilizing a DI framework).

  3. Create several unit tests for testing A in isolation by injecting different IB mocks into A (which can be challenging when A is a Form which is written to be executed within the context of a GUI event loop).

However, step 1 is trivial, since this can be done mostly automatically by standard Visual Studio refactorings, whilst step 2 and especially step 3 require programmers who know what they are doing. So the hard work are those steps 2 and 3, requiring 50 to 100 times more effort than step 1 (at minimum). Note also that there are probably several classes which don't require to mock every dependency to make them testable.

Hence I think it is pretty nonsensical to create tons of interfaces for every public class "just in case" - as long as noone is really going to create all those unit tests. This produces only boilerplate code which does not really increase maintainability of the system, because it is unclear if it will ever be used by anyone. I would recommend to start this by asking the question which unit tests shall be created, and when it comes to create one of these test, create the particular interfaces which are required for this specific test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.