2013-07-23 68 views
1

我的项目在规模和功能上都在不断增长,所以我决定使用NUnit测试一些功能,但是我面临的问题是大多数方法都是静态的,所以对我产生的第一件事是创建公共方法,我从单元测试类调用它们,但是这些公共方法开始很多,所以我想知道是不是在主类中创建新的Public方法,我应该创建一个接口,或者如果静态方法应该是Public使用类中间实例化。NUnit - Static Vs.公共方法

这是我的程序是如何构成的一个例子,

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(); 
    } 
} 

什么是保持彼此分离,我的程序和测试类的主要逻辑,最好的办法?

感谢,

回答

1

而是保持静态方法和添加非静态方法,最好是所有的方法转换从静止到实例方法和提取抽象其中Foo类的客户端将取决于:

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

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

静态成员将耦合引入您的应用程序。嘲笑静态会员真的很头痛。您应该program to abstraction, instead of programing to implementation为了使您的代码可测试和loosely coupled。当你的代码依赖于接口而不是静态类的,你可以很容易mock这种依赖性:

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(); 
+1

我将所有方法从静态移动到实例。感谢您提供有关抽象而不是实现的建议。 – m0dest0

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类,但而是应该为每个项目引用您的接口定义(一个用于实际实现,另一个用于您的测试项目)。

如果你的接口变得太大(阅读:太多的方法),那么你可以使用Repository Pattern,这会将你的方法分割成更多的函数接口。

+0

+1因为关于命名类和异常处理的提示,赞赏。谢谢Karl。 – m0dest0