我正在使用 MsTest 和 Moq 迈出第一步,并希望对 Linq2SQL 存储库类进行单元测试。 问题是我不希望单元测试永久修改我的开发数据库。
对于这种情况,哪种方法是最好的?
- 让每个测试在我的真实开发数据库上运行,但确保每个测试在自行清理后
- 为单元测试创建我的开发数据库和 dbml 的副本,并使用该上下文,以便我可以在每次测试运行之前清除整个数据库
- 查找一些模拟 Datacontext 的复杂方式(请记住,我完全是 Moq 菜鸟)。
- 完全不同的东西吗? 也许可以在每次测试运行之前自动为我设置数据库?
编辑:我刚刚了解到 MBUnit 有一个回滚属性,可以反转测试用例运行的任何数据库操作。 我并不是特别喜欢 MSTest,那么这是否可以轻松解决我的问题?
I am taking my first steps with MsTest and Moq and would like to unit test a Linq2SQL repository class. The problem is that I do not want the unit tests to permantly modify my development database.
Which would be the best approach for this scenario?
- Let each test operate on my real development database, but make sure each test cleans up after itself
- Create a duplicate of my development database and dbml for the unit test and use that context instead so I can clear the entire database before each test run
- Find some elaborate way of mocking the Datacontext (please bear in mind that I am a total Moq noob).
- Something completely different? Perhaps something that would automate setting up the database for me before each test run?
Edit: I just learned that MBUnit has a rollback attribute that reverses any database operations run by a test case. I am not particularly attached to MSTest, so could this be an easy answer to my problem?
发布评论
评论(3)
我使用一些包装类+基于 http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx。 请注意,我最终确实在我的假数据上下文包装器中实现了 SubmitChanges 逻辑,以测试我的实体的部分类实现中的验证逻辑。 我认为这确实是唯一棘手的部分,与托克利的实现有很大不同。
我将在下面包含我的 FakeDataContextWrapper 实现:
I went with mocking/faking the database using some wrapper classes + a fake implementation based on http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx. Note that I did end up implementing SubmitChanges logic in my fake data context wrapper to test out the validation logic in my entity's partial class implementation. I think that this was really the only tricky part which differed substantially from Tokeley's implementation.
I'll include my FakeDataContextWrapper implementation below:
我有类似的需求 - 对 Linq to Sql 类进行单元测试,因此我创建了一小组类来将模拟数据上下文、ITables 和 IQueryables 放入查询中。
我将代码放在博客文章“Linq to Sql 的模拟和存根”。 它使用起订量,并且可以为您所进行的测试提供足够的功能,而无需访问数据库。
I had a similar need - to unit test the Linq to Sql classes, so I made a small set of classes to get mock datacontext, ITables and IQueryables into the queries.
I put the code in a blog post "Mock and Stub for Linq to Sql". It uses Moq, and might provide enough functionality for the tests you're after without hitting the database.
我玩了一下 MBUnit,发现对于大多数测试用例,您可以通过使用 MBUnit 的 [ROLLBACK] 属性而无需模拟数据上下文。
不幸的是,在某些情况下,该属性会产生奇怪的副作用,例如从数据库加载 linq 实体,更改一个属性(不提交更改),然后再次加载相同的实体。 通常这会导致数据库上没有更新查询,但从测试方法内部来看,似乎只要我更改 linq 实体属性就会立即执行更新。
这不是一个完美的解决方案,但我想我会使用 [ROLLBACK] 属性,因为它比较省力并且对我来说效果很好。
I played a bit with MBUnit and learned that, for most test cases, you can get away without mocking the datacontext by using MBUnit's [ROLLBACK] attribute.
Unfortunately there are also cases when the attribute produces strange side effects, such as loading a linq entity from the database, changing one property (without submitchanges), then loading the same entity again. Usually this results in no update query on the database, but from within the Test Method it appears as if the update is immediately executed as soon as I change the linq entity property.
Not a perfect solution, but I think I'll go with the [ROLLBACK] attribute since it's less effort and works well enough for me.