运维开发网

c# – 我的Mocked DbContext使用Moq在单元测试中写入db

运维开发网 https://www.qedev.com 2020-05-16 15:36 出处:网络 作者:运维开发网整理
我是嘲笑和使用Moq的新手.这是我第一次尝试模拟添加功能.我有mocks设置,它适用于读取功能,但是当我尝试对add方法进行单元测试时,它会将更改保存到db. 如何模拟add方法? 我想我必须模拟我的UnitOfWork类,它有SaveChanges()方法.我想知道如何设置模拟来拦截对SaveChanges()的调用而不是保存到db. 这是我到目前为止的模拟 [SetUp] public
我是嘲笑和使用Moq的新手.这是我第一次尝试模拟添加功能.我有mocks设置,它适用于读取功能,但是当我尝试对add方法进行单元测试时,它会将更改保存到db.

如何模拟add方法?

我想我必须模拟我的UnitOfWork类,它有SaveChanges()方法.我想知道如何设置模拟来拦截对SaveChanges()的调用而不是保存到db.

这是我到目前为止的模拟

[SetUp]
    public void SetUp()
    {
        addCount = 0;

        IEnumerable<Platform> platformList = new List<Platform>(){
            new Platform() { Id = 1, Name = "Unknown"},
            new Platform() { Id =2, Name = "Amazon"},
            new Platform() { Id = 3, Name = "Prime Pantry"}
        };
        var platformData = platformList.AsQueryable();

        var mockPlatformSet = new Mock<DbSet<Platform>>();
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.Provider).Returns(platformData.Provider);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.Expression).Returns(platformData.Expression);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.ElementType).Returns(platformData.ElementType);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.GetEnumerator()).Returns(platformData.GetEnumerator());
        mockPlatformSet.Setup(m => m.Add(It.IsAny<Platform>())).Callback(() => addCount++);

        var mockContext = new Mock<ApplicationDbContext>(){ CallBase = true };
        mockContext.Setup(m => m.Platforms).Returns(mockPlatformSet.Object);
        mockContext.Setup(m => m.Platforms.Add(It.IsAny<Platform>()));
        mockContext.Setup(m => m.Platforms.Add(It.IsAny<Platform>())).Callback(() => addCount++);


        unitOfWork = new UnitOfWork(mockContext.Object);
        platformRepo = new PlatformRepository(mockContext.Object);

        controller = new PlatformController(platformRepo, unitOfWork);
    }

添加UnitOfWork代码

public class UnitOfWork : IUnitOfWork 
{
    private readonly DbContext _context;
    private bool _isDisposed = false;

    public UnitOfWork(DbContext context)
    {
        _context = context;
    }

    public void SaveChanges()
    {
        _context.SaveChanges();
    }

    protected Virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _isDisposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

}

更新的问题

我正在尝试单元测试我的PlatformController的Create方法.在这个方法中,我在repostiory上调用Add函数,然后调用UnitOfWork的SaveChanges函数.我想验证我的Platform对象是否被添加到DbSet,但是“拦截”对SaveChanges()的调用,它不会写入db.

我怎样才能做到这一点?

当我将mockContext的CallBase值设置为IUnitOfWork为false时,这似乎解决了我的单元测试写入数据库的问题.

这行代码:

mockContext.As< IUnitOfWork>().CallBase = false;

这是我的安装功能的代码

[SetUp]
    public void SetUp()
    {
        addCount = 0;

        IEnumerable<Platform> platformList = new List<Platform>(){
            new Platform() { Id = 1, Name = "Unknown"},
            new Platform() { Id =2, Name = "Amazon"},
            new Platform() { Id = 3, Name = "Prime Pantry"}
        };
        var platformData = platformList.AsQueryable();

        var mockPlatformSet = new Mock<DbSet<Platform>>();
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.Provider).Returns(platformData.Provider);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.Expression).Returns(platformData.Expression);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.ElementType).Returns(platformData.ElementType);
        mockPlatformSet.As<IQueryable<Platform>>().Setup(m => m.GetEnumerator()).Returns(platformData.GetEnumerator());
        mockPlatformSet.Setup(m => m.Add(It.IsAny<Platform>())).Callback(() => addCount++);

        var mockContext = new Mock<ApplicationDbContext>(){ CallBase = true };
        mockContext.Setup(m => m.Platforms).Returns(mockPlatformSet.Object);
        mockContext.Setup(m => m.Platforms.Add(It.IsAny<Platform>()));
        mockContext.Setup(m => m.Platforms.Add(It.IsAny<Platform>())).Callback(() => addCount++);
        mockContext.Setup(m => m.Set<Platform>()).Returns(mockPlatformSet.Object);
        mockContext.As<IUnitOfWork>().CallBase = false;

        unitOfWork = new UnitOfWork(mockContext.Object);
        platformRepo = new PlatformRepository(mockContext.Object);

        controller = new PlatformController(platformRepo, unitOfWork);
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消