2013-07-23 66 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