繁体   English   中英

为TDD存储库模拟DbContext

[英]Mocking DbContext for TDD Repository

试图模拟与存储库耦合的EF上下文。 我正在使用Moq,尝试设置模拟的Context并通过构造函数将其传递到存储库中。

之后,我调用Add方法,以简单地添加一个新对象,然后我通过检查传入的上下文是否已更改状态来尝试声明...

我收到的错误是NullReference异常,我猜是因为我的模拟不正确。

这是代码:

用不工作的模拟进行测试

[TestClass]
public class GameRepositoryTests
{
    [TestMethod]
    public void PlayerThatWonMustBeAddedToTopList()
    {
        // Arrange
        var expected = "Player added successfully";

        var dbContextMock = new Mock<Context>();
        // Need to setup the Context??

        IRepository gameRepository = new GameRepository(dbContextMock.Object);

        var user = "MyName";

        // Act
        gameRepository.Add(user);

        // Assert

        dbContextMock.VerifySet(o => o.Entry(new ScoreBoard()).State = EntityState.Added);
    }
}

public class ScoreBoard
{

}

知识库

public class GameRepository : IRepository
{
    private readonly Context _context;

    public GameRepository()
        : this(new Context())
    {
        // Blank!
    }

    // Passing in the Mock here...
    public GameRepository(Context context)
    {
        this._context = context;
    }

    // Method under test...
    public void Add<T>(T entity) where T : class
    {
        _context.Set<T>().Add(entity);
    }
}

上下文

public class Context : DbContext
{
    public Context()
        : base("name=DefaultConnection")
    {

    }
}

您需要模拟Set<T>()调用。

这样的事情应该可以解决。

// Arrange
var context = new Mock<Context>();
var set = new Mock<DbSet<User>>();

context.Setup(c => c.Set<User>()).Returns(set.Object);

// Act

// Assert
set.Verify(s => s.Add(It.IsAny<User>()), Times.Once());

除了在基础DbSet上调用Add()之外,您实际上不需要进行任何验证。 无需对Entity状态已被修改的事实进行验证。 如果您确认调用了Add() ,那应该足够了,因为您可以放心地假设EF正常工作。

本示例仅适用于您的User对象的存储库。 您必须以这种方式为要测试的每个存储库分别设置模拟。 如果需要,您可能会编写一个更通用的版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM