使用Moq测试存储库更新或插入

时间:2015-01-06 12:25:07

标签: moq unit-testing

我有这样的方法:

public int InsertOrUpdateCustomer(Customer customer)
{
var result = default(int);
try
{
    using (var customerContext = new Customer())
    {
        var customerResult = customerContext.UpdateGraph(coupon, map => map.OwnedCollection(p => p.CustomerPoints));
        couponsContext.SaveChanges();
        result = customerResult.CustomerTypeID;
    }
}
catch (Exception ex)
{
    // Log the Exception
}
return result;
}

它创建CustomerContext的实例,保存并返回新的CustomerID。

我正在尝试使用Moq并使用此方法,其中测试需要检查返回的整数值。

[TestMethod]
public void Inserting_A_Customer_Should_Return_A_IntegerValue(Customer customer)
{
    var mock = new Mock<ICustomerRepository>();
    int customerId = 1;
    mock.Setup(c => c.InsertOrUpdateCustomer(customer)).Returns(new Customer() { Id = customerId });
}

这给出了这个错误:

cannot convert from 'Entities.Commerce.Customer' to 'System.Func<int>'

我也是Moq的新手。

我想从这个问题中得知,如果有一个像上面这样的代码,那么如何继续编写单元测试。

如果在了解该过程时会给出一些指示,那将会非常有帮助。

提前致谢。

1 个答案:

答案 0 :(得分:2)

错误本身是因为您正在设置的方法具有此签名:

public int InsertOrUpdateCustomer(Customer customer)

而您的设置正在尝试退回客户

 mock.Setup(c => c.InsertOrUpdateCustomer(customer))
     .Returns(new Customer() { Id = customerId });

更改此项以返回虚假的整数,例如.Returns(42);,可以避免错误。

不太好的消息是,如果测试的目的是Inserting_A_Customer_Should_Return_A_IntegerValue,你将嘲笑你试图测试的东西(你只是在测试Moq)。

你需要做的是Moq你的DbContext,这使得这条线有问题,因为它紧密耦合:

 using (var customerContext = new CustomerContext())

这里的建议是允许将DbContext注入到您正在测试的类的构造函数中(或者注入一个可以创建DbContext的工厂接口)。

然后你可以根据这个MSDN article here模拟DbContext和相关的IDbSetsCustomers),然后你可以将它注入你正在测试的类中,并测试任何逻辑/分支在你班上。