2011-07-28 53 views
15

我正在使用Rhino Mocks作爲單元測試的嘲諷框架。無法使用Rhino Mocks創建內部類型的模擬類

我有一個名爲Subject的類,它是我想測試的類。它依賴於IStore。

IStore定義如下:

//internal interface : has InternalsVisible to both "Subject" 
//and "StoreTests" class namespaces 
internal interface IStore { 
    void Store(string name); 
    //other methods 
} 

和主題類被定義爲如下:

class Subject : IStore { 
    private IStore internalStore; 

    //constructor injection 
    void Subject(IStore store) { 
     internalStore = store; 
    } 

    void Store(string name) { 
     internalStore.Store(name); 
    } 

    //other methods 
} 

使用RhinoMocks我的測試類如下:

//test class 
class StoreTests { 
    Subject subject = new Subject(); 

    [Test] 
    public StoreTest() { 
     //Arrange 
     var mockStore = MockRepository.GenerateMock<IStore>(); 
     string testName = "test"; 
     mockStore.Expect(x => x.Store(testName)).Returns(null); 

     //Act 
     subject.Store(testName); 

     //Assert 
     mockStore.VerifyAllExpectations(); 
    } 

    //other test methods 
} 

在我的設置,界面被定義爲內部,並且它具有爲Subject類和Sto設置的InternalsVisible重新測試課程。但是,當測試用例執行時,它會在var mockStore = MockRepository.GenerateMock();時引發異常。 表示IStore不公開,因此無法生成模擬。

我認爲這是因爲IStore不公開。但是,由於我已經在IStore dll上設置了InternalsVisibleTo,它會不足以讓StoreTests爲該類創建一個模擬?

現在我認爲這個問題可以通過公開IStore接口來解決。但是鑑於這不是我的選擇,有沒有其他方法可以爲IStore創建模擬?

回答

27

你嘗試使裝配內部可見犀牛嘲笑?

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")] 

有關詳細信息,請參閱Rhino Mocks Internal Members

當一個類被模擬時,在運行時產生一個新的類,它是從模擬類派生的。這個生成的類位於一個名爲「DynamicProxyGenAssembly2」的單獨的「臨時」程序集中。因此,InternalsVisibleTo屬性需要在目標程序集上設置,以允許從臨時程序集訪問其內部成員;否則,模擬對象無法覆蓋內部成員,因爲它無法訪問它(這也是爲什麼模擬方法必須標記爲虛擬)。請注意,即使單元測試和測試類位於同一個程序集中,情況也是如此。

所以,你需要確保目標類的組件使得其內部的代理組件可見這樣(在AssemblyInfo.cs中爲例):

+1

感謝您的鏈接!它現在有效。 – Santhosh

10

是的,應該足以補充以下的的AssemblyInfo.cs文件組件的測試下:

[assembly: InternalsVisibleTo("Tests.Assembly.Name")] 
[assembly: InternalsVisibleTo("NUnit.Framework")] 
[assembly: InternalsVisibleTo("Rhino.Mocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D1CF4B75B7218B141AC64C15450141B1E5F41F6A302AC717AB9761FA6AE2C3EE0C354C22D0A60AC59DE41FA285D572E7CF33C320AA7FF877E2B7DA1792FCC6AA4EB0B4D8294A2F74CB14D03FB9B091F751D6DC49E626D74601692C99EAB7718ED76A40C36D39AF842BE378B677E6E4EAE973F643D7065241AD86ECC156D81AB")] 
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 
+0

這個答案也很好。將其他標記爲已接受,僅僅是因爲它提供了wiki中其他信息的鏈接。 – Santhosh

3

嗯,這可能會回答,但對於我沒有工作。

所以,這是我做了什麼使其工作(可能幫助他人,甚至我,在下一個項目....):

在Visual Studio工具菜單: 外部工具: 添加名字我把「LongStrongName」,但放在任何你覺得適合:

(這條道路,或是其他地方的SN.EXE是你):

Command: 
    C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe 
Arguments: 
    -Tp $(TargetPath) 

(點擊複選框,輸出爲「使用輸出窗口」)

現在,您可以點擊項目,然後轉到工具,然後轉到「LongStrongName」菜單:

和VS將輸出:

Public key is  0240000048000009400000006020000002400005253413100040000010001009badbe86c32ec0 
ec429f0b3909********* 

Public key token is 6ccc051******** 

打開assembly.cs並添加:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 

添加你需要的任何組件,瞧(我不得不把多個程序集)。

相關問題