Moq框架:模拟添加对象

Moq framework: simulating adding an object

我刚开始使用 Moq 进行单元测试,在尝试向我们的存储库添加对象时遇到了 运行 问题。基本上,我们有一个代表我们数据库结构的接口。此接口包含表示该数据库中数据的其他接口,如下所示:

public interface IUnitOfWork : IDisposable
{
    IRepository<Order> OrdersRepo { get; }
    IRepository<Customer> CustomerRepo { get; }
    IRepository<Product> ProductsRepo { get; }
}

创建模拟 IUnitOfWork 没问题,当我尝试向 OrdersRepo 添加订单对象时出现问题,如下所示:

[TestClass]
public class OrderTest
{
    private Mock<IUnitOfWork> mockDB = new Mock<IUnitOfWork>();
    private IUnitOfWork testDB;
    private Order testOrder;

    [TestInitialize]
    public void Initialize()
    {
        //Create the test order
        testOrder = new Order();
        testOrder.ID = 123;

        //Setting up the Moq DB
        testDB = mockDB.Object;
    }

    [TestMethod]
    public void AddOrder_ValidOrder_OrderAdded()
    {   
        testDB.OrdersRepo.Add(testOrder);
    }
}

当我尝试添加订单时,我总是收到 NullReferenceException。我想这是因为testDB里面的OrdersRepo是一个接口。但是,当我尝试为此创建一个模拟回购时,我收到一条错误消息,指出 OrdersRepo 是只读的,因为它是 { get; } 而不是 { get;放; }.

我是否可以使用 Moq 来测试在 repo 仅 get 时添加我的订单对象;是一个接口?

您收到 NullReferenceException 是因为您尚未设置模拟对象。如果只想设置 1 属性,请使用

mockDB.SetupProperty(self => self.OrdersRepo);

如果你想设置属性使用你自己的枚举,你可以使用

var collection = <Init collection here>;
mockDB.SetupGet(self => self.OrdersRepo).Returns(collection);

或者,如果您想设置所有属性,您可以使用

mockDB.SetupAllProperties();

如果你想测试你的订单回购,那么你不需要通过 IUnitOfWork 然后模拟订单回购,因为那样你就不会测试你的主题。您应该实例化 Orders 存储库的具体实例并调用应该可公开访问的 Add 方法。也许您需要模拟您的底层数据库客户端,您的订单回购正在调用以调用数据库,但这是另一回事了。

希望对您有所帮助。