2011-04-19 114 views
1

我有一些Web編程方法需要編寫單元測試。他們需要訪問數據庫,所以,我自然想要Moq這一部分。用Moq嘲諷繼承類

存儲類通過接口訪問,實現API方法的類繼承接口。我不知道的是如何模擬是單元測試中的繼承接口。

public class CreateWishList : APIAccess 
{ 
    public long CreateWishListV1(long userId, string wishListName) 
    { 
     // Do stuff like 
     long result = Storage.CreateWishList(userId, wishListName); 

     return result; 
    } 
} 

public class APIAccess 
{ 
    protected IStorage Storage { get; private set; } 

    public APIAccess() : this(new APIStorage()) { } 

    public APIAccess(IStorage storage) 
    { 
     Storage = storage; 
    } 
} 

public interface IStorage 
{ 
    long CreateWishList(long userId, string wishListName); 
} 

所以,我想單元測試CreateWishListV1(...)方法,要做到這一點,而不數據庫訪問,我需要模擬什麼Storage.CreateWishList(...)回報。我怎麼做?

UPDATE:

我想是這樣的:

[Test] 
public void CreateWishListTest() 
{ 
    var mockAccess = new Mock<APIAccess>(MockBehavior.Strict); 
    mockAccess.Setup(m => m.Device.CreateWishList(It.IsAny<long>(), It.IsAny<string>())).Returns(123); 

    var method = new CreateWishList(); 
    method.Storage = mockAccess.Object; 

    long response = method.CreateWishListV1(12345, "test"); 

    Assert.IsTrue(response == 123, "WishList wasn't created."); 
} 

只好在APIAccess改變Storage財產公開爲好。

+1

你究竟想要測試什麼?你爲什麼要模擬調用CreateWishListV1?我認爲那是你想測試的方法? – sloth 2011-04-19 11:52:52

+0

是的,我做錯了。更新了問題;那個更好嗎? – Edgar 2011-04-19 11:58:05

回答

1

關閉我的頭頂:

var storage = new Mock<IStorage>(); 
storage.Setup(x => x.CreateWishList(It.IsAny<long>(), It.IsAny<string>()) 
     .Returns(10); 

然後用自己的構造受理IStorage創建CreateWishList對象。

var createWishList = new CreateWishList(storage.Object); 

要單元測試您的CreateWishList()方法,您將編寫一個單獨的測試。這個測試應該純粹通過檢查CreateWishListV1()中的代碼。

+0

有沒有辦法做到這一點,而無需創建構造函數? – Edgar 2011-04-19 11:45:00

+0

你可以讓'Storage'屬性公開,以便單元測試可以設置它。無論哪種方式 - 當你實例化對象內的依賴關係時,你不能指望單元測試分配依賴關係。 – 2011-04-19 11:49:19

+3

是的,你可以通過屬性注入IStorage,或者通過反射來設置它。但創建一個接受IStorage的構造函數將是最乾淨的方式。 – sloth 2011-04-19 11:55:10