2011-04-19 89 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