如何使用模拟存储库来测试 CRUD?
How to use mocked repository for testing CRUD?
我知道有很多这样的 questions/articles 我已经读了很多遍了,但我还是卡住了。
我有一个非常简单的代码。 Database=>Entity Framwork=>Repository=>Logic=>Display and now tests。我的问题是我找不到任何帮助来测试我的 CRUD 操作。我只有以下说明:"Test with mocked repository"。所以下面的就没问题了
[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 在这里应该是什么?
任何帮助,甚至 link 都非常适合。谢谢。
编辑:澄清
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
本身在发布前已经过 Microsoft 测试。无需测试 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
}
我知道有很多这样的 questions/articles 我已经读了很多遍了,但我还是卡住了。
我有一个非常简单的代码。 Database=>Entity Framwork=>Repository=>Logic=>Display and now tests。我的问题是我找不到任何帮助来测试我的 CRUD 操作。我只有以下说明:"Test with mocked repository"。所以下面的就没问题了
[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 在这里应该是什么?
任何帮助,甚至 link 都非常适合。谢谢。
编辑:澄清
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
本身在发布前已经过 Microsoft 测试。无需测试 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
}