我正在使用 Entity Framework 4.1 进行数据库访问,并希望对以下代码进行单元测试:
// Get all the entities including children
using (MyContext context = new MyContext())
{
return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}
我正在使用 Moles 来消除数据库依赖项,但是我陷入了困境。我应该开始找出实体框架中的哪一点。
我正在关注这个 示例,但它适用于 LINQ-To-SQL。
我还考虑调试/跟踪实体框架,以找出在调用数据库之前拦截哪个函数。
但是,似乎没有可供 Entity Framework 4.1 跟踪的源代码。请参阅讨论。
谁能指导我应该在 DbContext 中调出哪些函数,以便我可以获得 EmployeeProfiles 列表?
I am using Entity Framework 4.1 for database access and would like to Unit Test the following code:
// Get all the entities including children
using (MyContext context = new MyContext())
{
return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}
I am using Moles to mole out the database dependency however I am stuck. Which point in the Entity Framework I should begin to mole out.
I was following this example but it is for LINQ-To-SQL.
I was also thinking of debugging/tracing the Entity Framework to figure out which function to intercept out before the call to the database is made.
However, it seems that there is no source code available for Entity Framework 4.1 to trace with. See discussion.
Can anyone guide me to which function(s) I should be moling out in the DbContext so I can get a list of EmployeeProfiles back?
发布评论
评论(2)
在我看来,您不是通过存储库模式消除对 EF 的依赖,而是尝试模拟 EF 的特定行为。我看不出尝试这样做有什么意义,而且这会非常困难,EF 不应该被嘲笑。
您的存储库大概是这样的:
这样您就删除了存储库对 EmployeeProfiles 如何返回的依赖。现在您可以模拟您的心意(尚未使用 Moles),但是使用 Moq,您可以执行以下操作:
因此,如果您将想要从数据库抽象的方法/属性放入存储库接口,然后您可以模拟出您想要测试它可能返回的任何值。
也许你无论如何都会这样做,我不确定。我不明白你为什么要对 EF 进行单元测试,你希望获得什么?这将是非常困难的,它不是为了被嘲笑而设计的(很少有接口/虚拟)。对您返回的数据的任何模拟(这实际上是您真正感兴趣的数据)都将按照上面的方式完成。
It looks to me like rather than removing the dependency on EF via a Repository pattern, you're trying to mock the specific behaviour of EF. I can't see the point in trying to do that and it would be very difficult, EF isn't meant to be mocked.
Your repository is presumably something like this:
This way you have removed the repository dependency on how the EmployeeProfiles is returned. Now you can mock-away to your heart's content (haven't yet used Moles), but with Moq, you would do something like:
So, if you put the methods/properties you want to abstract away from the database into the repository interface, then you can mock out any values you want to test that it might return.
Maybe you're doing this anyway, I'm not sure. I don't see why you'd want to unit test EF, what would you hope to gain? It would be immensely hard, it's not designed to be mocked (very few interfaces/ virtuals). Any mocking of data you return, which is really all you are really interesting in would be done as above.
这是完全可能的,而且在我看来,是有效的。是的,您可以使用存储库模式并模拟您的存储库,通常这就足够了。
然而,我见过两个关于模拟 EF 的论点:
目前这有点像一场圣战,但有一些论据支持你正在做的事情。
因此,要对 Moles 执行此操作,您需要做两件事。首先,更改创建 DbContext 的模板,以便所有表的返回类型均为
IDbSet
而不是DbSet
。然后,在您的测试项目中,添加 IDbSet 的测试类实现。我发现这个效果很好。
现在,在测试中,您可以执行以下操作:
它快速、简单,并且允许您测试代码,直到它脱离您的控制。
This is totally possible, and in my opinion, valid. Yes, you can use a repository pattern and mock your repository, and often that is good enough.
However, two arguments I've seen for mocking EF:
This is a bit of a holy war at this point, but there are arguments out there that support what you are doing.
So, to do this with Moles, you'll need to do two things. First, change the template that creates your DbContext so that the return types of all your tables are
IDbSet<>
instead ofDbSet<>
.Then, in your test project, add a test class implementation for IDbSet. I've found this one to work well.
Now, in your test, you can do the following:
It's quick, simple, and allows you to test your code right up to the very point it leaves your control.