在阅读了有关单元测试实体框架的几个问题/答案后,我决定放弃单元测试以进行集成测试。我的理念是,与 EF 上下文交互是一种“私人”操作,因为它不需要独立于我的服务进行单元测试,也不能轻松准确地被嘲笑。
注意:在我的示例中,我使用的是 EF5。
首先,我有一个创建用户的服务方法:
void CreateUser(string username, string password);
我的测试程序集有一个 SetUpFixture(测试运行一次性),它创建我的数据库(EF 代码优先)和测试数据:
[SetUpFixture]
public class SetUpFixture
{
[SetUp]
public void SetUp()
{
using (var context = new MyDbContext())
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
// Set up a bunch of initial data and commit
}
}
}
然后在每次测试之前,我的 TestFixtureSetup 方法运行创建我的数据库上下文的实例,该实例设置为在释放时回滚(在每次测试之后),并且还创建我的服务实例:
[TestFixtureSetUp]
public virtual void TestFixtureSetUp()
{
_context = new MyContext(rollbackOnDispose: true);
UserService = new SignupService(_context);
}
[TestFixtureTearDown]
public virtual void TestFixtureTearDown()
{
Context.Dispose();
}
最后,我进行了实际的集成测试,以确保传入了哪些有效数据,创建了带有我的用户名的记录(这就是我的问题所在):
[Test]
public void ValidDataShouldResultInNewRecordWithUsername()
{
SignupService.CreateUser("myuser", "fakepassword");
var q = from user in Context.Users
where user.Username == "myuser"
select user;
var actualUser = q.Single();
Assert.AreEqual("myuser", actualUser.Username);
}
以下是我的问题:
1)首先,这甚至是测试依赖于EF的服务的方式吗?我知道有几种方法,我只是想确保这种方法没有什么疯狂的。
2)其次,我应该如何验证服务方法(CreateUser)在提交数据之前完成了它应该做的事情(我不希望它提交,以便我的数据库状态保持在它之前的初始化状态每次测试)?上面测试中的查询没有返回数据,因为它还没有提交。