1

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,

4

2 回答 2

1

与其保留静态方法并添加非静态方法,不如将所有方法从静态方法转换为实例方法并提取 Foo 类的客户端所依赖的抽象:

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

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

静态成员将耦合引入您的应用程序。模拟静态成员真的很头疼。您应该对抽象进行编程,而不是对实现进行编程,以使您的代码可测试且松散耦合。当您的代码依赖于接口而不是静态类时,您可以轻松地模拟此依赖项:

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

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

如果你真的需要在全局范围内访问这些方法(这不是一个好主意 - 这是一种程序化的编程风格),那么将你的类实现为Singleton

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

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

您将能够在应用程序的任何位置获取类实例

IFoo foo = Foo.Instance;
foo.SortUser();
于 2013-07-23T16:41:33.577 回答
1

在我看来,你应该让你的真实类和你的单元类都实现一个通用接口,如下所示:

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

对于您的实际实现,请使用以下命令:

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

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

对于您的测试课程,请使用:

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

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

注意:您的FakeFoo类不需要与您的类存在于同一位置RealFoo,而是IFoo每个项目都应该引用您的接口定义(一个用于实际实现,另一个用于测试项目)。

如果您的IFoo接口变得太大(阅读:方法太多),那么您可以使用Repository Pattern,它会将您的方法更多地按照功能线分割成接口。

于 2013-07-23T16:52:36.653 回答