我知道有很多这样的问题/文章,我已经读过很多次了,但是我仍然很困惑。
我有一个非常简单的代码。数据库=>实体框架=>存储库=>逻辑=>显示并立即测试。我的问题是我找不到如何测试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而不是我的实际数据库。我应该以某种方式创建假课程吗?
答案 0 :(得分:1)
您的存储库只是包装DbContext
。 DbContext
本身已经在发布之前经过Microsoft的测试。无需测试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
}
以上测试验证了与包装的{{1}}相关的调用的预期行为,并且在安全性方面并没有提供太多帮助,因为它基本上是在测试包装的代码是否被调用。
理想情况下,应该对存储库进行模拟并用于更高级别的逻辑测试
{{1}}