繁体   English   中英

如何使用模拟存储库来测试 CRUD?

[英]How to use mocked repository for testing CRUD?

我知道有很多这样的问题/文章,我已经多次阅读了很多,但我仍然卡住了。

我有一个非常简单的代码。 数据库=>实体框架=>存储库=>逻辑=>显示,现在进行测试。 我的问题是我找不到任何帮助来测试我的 CRUD 操作。 我只有以下说明:“使用模拟存储库进行测试”。 所以下面的问题是没有问题的。

    [Test]
    public void TestThatReadCrewWorks()
    {
        CrewLogic logic = new CrewLogic();
        var result = logic.LReadCrew(102);
        Assert.That(result.Name, Is.EqualTo("Test Joe"));
    }

如何使用我的存储库(使用 dbcontext)独立测试,而不给测试 dll 连接字符串? 我试过了...

    [Test]
    public void TestThatCreatingCrewWorks2()
    {
        DbContext ctx;
        CrewRepository newc = new CrewRepository(ctx);
    }

...从这里完全黑暗。 dbcontext 应该是什么?

任何帮助,甚至链接都是高度合适的。 谢谢你。

编辑:澄清

public abstract class Repository<T> : IRepository<T>
    where T : class
{
    protected DbContext ctx;

    public Repository(DbContext ctx)
    {
        this.ctx = ctx;
    }

    public T Read(int id)
    {
        return this.ctx.Set<T>().Find(id);
    }
    //...and other crud operations
 }

我有这个语法。 我如何编写依赖于这个一般 DBcontext 而不是我的实际数据库的测试。 我应该以某种方式创建假 class 吗?

您的存储库只是包装DbContext DbContext本身在发布之前已经通过了微软的测试。 无需测试DbContext是否符合其设计目的。

要测试存储库是否按预期使用了上下文,您需要使用实际上下文进行集成测试。 模拟DbContext或使用内存中的DbContext 无论哪种方式,您的测试都会给人一种错误的安全感,因为您基本上是在测试已经由其开发人员测试过的包装代码。

例如你的return this.ctx.Set<T>().Find(id); 在基础存储库中。 该行中的所有内容都与DbContext相关,不值得您测试它应该做的事情。

例如,查看以下相同存储库方法的测试

[Test]
public void CrewWorks_Should_Find_By_Id() {
    //Arrange
    int expectedId = 102;
    string expectedName = "Test Joe";
    Crew expected = new Crew {
        Id = expectedId,
        Name = "Test Joe"
    };
    Mock<DbContext> ctxMock = new Mock<DbContext>();
    ctxMock
        .Setup(_ => _.Set<Crew>().Find(expcetedId))
        .Returns(expected);
    DbContext ctx = ctxMock.Object;
    CrewRepository subject = new CrewRepository(ctx);

    //Act
    Crew actual = subject.Read(expectedId);

    //Assert
    Assert.That(actual, Is.EqualTo(expected));
}

上面的测试验证了包装的DbContext相关调用的预期行为,并没有真正提供太多的安全性,因为它基本上是在测试包装的代码是否被调用。

理想情况下,应该模拟存储库并用于在更高级别测试逻辑

[Test]
public void TestThatReadCrewWorks() {
    int expectedId = 102;
    string expectedName = "Test Joe";
    Crew expected = new Crew {
        Id = expectedId,
        Name = "Test Joe"
    };
    //Assuming abstraction of specific repository 
    //  interface ICrewPrepsitory: IRepository<Crew> { }
    ICrewPrepsitory repository = Mock.Of<ICrewPrepsitory>(_ =>
        _.Read(expectedId) == expected
    );

    CrewLogic logic = new CrewLogic(repository); //assuming injection

    //Act
    var actual = logic.LReadCrew(expectedId);

    //Assert
    Assert.That(actual.Name, Is.EqualTo(expectedName));
    //...other assertions
}

暂无
暂无

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

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