m0dest0
m0dest0

Reputation: 859

NUnit - Static Vs. Public methods

My project has been growing in size and in functionality so I decided to test some features using NUnit however the problem I'm facing is that most of the methods are Static, so the first thing that ocurred to me was create public methods and I am calling them from the Unit Test class however those public methods are beginning to be many, so I wonder if rather than create new Public methods inside the main class, I should create an interface or if the Static ones should be Public and be instantiated using an class intermediate.

This is an example of how my program is structured,

namespace Mynamespace
{
    public class Foo
    {
         InsertUser();
         SortUser();
    }

    static void InsertUser()
    {

    }

    static void SortUser()
    {

    }

    //Here start the public methods to be called from the unit test class

    public DoSort() 
    {
        InsertUser();
        SortUser();
    }
}

What's the best approach to keep separated the main logic of my program and the testing classes?

Thanks,

Upvotes: 1

Views: 3107

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

Instead of keeping static methods and adding non-static methods, it's better to convert all your methods from static to instance methods and extract abstraction which clients of Foo class will depend on:

public interface IFoo
{
     void InsertUser();
     void SortUser();
}

public class Foo : IFoo
{
     void InsertUser() { ... }
     void SortUser() { ... }
}

Static members introduce coupling into your application. And it's a real headache to mock static members. You should program to abstraction, instead of programing to implementation in order to make your code testable and loosely coupled. When your code depend on interface instead of static class, you can easily mock this dependency:

Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Setup(f => f.InsertUser()).Throws<InvalidOperationException>();

var sut = new ClassUnderTest(fooMock.Object);
fooMock.VerifyAll();

And if you really need to access these methods in global scope (which is not very good idea - it's a procedural style of programming), then implement your class as Singleton:

public class Foo : IFoo
{
     public static Foo Instance = new Foo(); // simple singleton implementation
     private Foo() { }

     void InsertUser() { ... }
     void SortUser() { ... }
}

You will be able to get class instance anywhere in your application

IFoo foo = Foo.Instance;
foo.SortUser();

Upvotes: 1

Karl Anderson
Karl Anderson

Reputation: 34846

In my opinion, you should have your real classes and your unit classes both implementing a common interface, like this:

interface IFoo
{
    void InsertUser();
    void SortUser();
}

For your actual implementation, use this:

public class RealFoo : IFoo
{
    public void InsertUser()
    {
        throw new NotImplementedException();
    }

    public void SortUser()
    {
        throw new NotImplementedException();
    }
}

For your testing classes, use this:

public class FakeFoo : IFoo
{
    public void InsertUser()
    {
        throw new NotImplementedException();
    }

    public void SortUser()
    {
        throw new NotImplementedException();
    }
}

Note: Your FakeFoo class would not need to exist in the same location as your RealFoo class, but rather your IFoo interface definition should be referenced by each of the projects (one for real implementation and the other in your test project).

If your IFoo interface becomes too large (read: too many methods), then you can use the Repository Pattern, which would segment your methods into interfaces more along the lines of functionallity.

Upvotes: 1

Related Questions