我正在考虑制作一个可以在单元测试中使用的可模拟 DataContext
。描述了一种方法 here .但是,这种方法的问题是对存储库的更改会立即生效——在调用 Commit
(或任何其他等效于 SubmitChanges
)之前。
另一方面,要包含正确的 SubmitChanges
行为将涉及从 DataContext
复制大量复杂代码,并可能导致更多错误。
模拟内存存储库(不等待 SubmitChanges
)的简单实现对于使用单元测试是否可行?这通常是如何完成的?
最佳答案
如果我的理解是正确的,那么你还没有完全确定你的 SUT (Subject Under Test)。
如果你想测试与数据库的连接,那么我们正在谈论一个集成测试,你不应该模拟你的
DataContext
如果您想测试调用
DataContext
的逻辑,那么这是一个单元测试
在任何情况下,我建议您将对 DataContext
的调用包装在存储库中,存储库将负责与数据库对话,然后执行此操作方法会让事情变得更容易
我会用一个例子来阐明它,最后我会推荐几个链接来帮助你编写可测试的代码。 (我总是这样说,我会再说一遍,编写测试很容易,真正的努力必须放在编写干净的可测试代码上)
public interface IMyRepository
{
void ChangeEmail(int employeeId, string newEmail);
}
public class MyRepository : IMyRepository
{
private MyDataContext context;
public MyRepository(MyDataContext context)
{
this.context = context;
}
public void ChangeEmail(int employeeId, string newEmail)
{
//save your email using your context
}
}
现在在您的消费者代码中,您将注入(inject)您的存储库:
public class MyCommand
{
public MyCommand(IMyRepository myRepository)
...
public void ChangeEmail(int employeeId, string newEmail)
{
//adding condition just to clarify how to test
if(this.AllowChangeEmail(employeeId))
{
this.myRepository.ChangeEmail(employeeId, newEmail);
}
else
{
throw new DomainException("this should not happen");
}
}
...
}
我们解耦了DataContext
的使用,从你的域代码的角度来看,DataContext
不存在,域知道的唯一代码是IMyRepository
并且由于它是一个接口(interface),您可以轻松更改提供者来更改应用程序的行为,而无需重构您的域代码
如果您注意到我还没有谈到测试,为什么?因为就像我说的,首先要做的是编写干净的可测试代码(不要误解这一点,应该遵循 TDD,这意味着应该首先编写测试,我遵循这种方法只是为了演示)现在我们有了这段代码,让我们看看测试我们应用程序的逻辑有多容易而是使用 AutoFixture 等工具, FluentAssertions和 Moq
public class MyFakeProvider : IMyRepository
{
public void ChangeEmail(int employeeId, string newEmail)
{
//write some assert here indicating the method was called
}
}
[Test]
public void MyTest()
{
var myMock = new MyFakeProvider();
var sut = new MyCommand(myMock);
sut.Invoking(x => x.ChangeEmail(3, "my@email.com")).ShouldNotThrow();
}
这些链接只关注一件事:编写可测试的代码:
http://misko.hevery.com/code-reviewers-guide/
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
http://misko.hevery.com/presentations/
http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded
http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded
http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded
http://www.youtube.com/watch?v=4F72VULWFvc&feature=player_embedded
关于c# - 在内存中模拟 LinqToSql 存储库以用于单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10377135/