简体   繁体   English

单元测试实体框架

[英]Unit Testing Entity Framework

I have just started using Entity Framework(v4) and Linq.我刚刚开始使用 Entity Framework(v4) 和 Linq。

I have a Entity data model, which has been generated from a database.我有一个实体数据 model,它是从数据库生成的。 I have then implemented repository classes in order to implement the business logic for my entities and they contain my LINQ queries for interacting with the entities/database.然后我实现了存储库类,以便为我的实体实现业务逻辑,它们包含我的 LINQ 查询,用于与实体/数据库交互。

What is the easiest and simplest way to unit test the methods/functions in my repository classes without hitting the database?在不访问数据库的情况下对存储库类中的方法/函数进行单元测试的最简单和最简单的方法是什么?

You can run your tests against an inmemory database.您可以针对内存数据库运行测试。 Check this question检查这个问题

Find a framework that would allow you to create a mock-up repository.找到一个允许您创建模型存储库的框架。 This will take time at the start, but will pay off in a long term run.这在开始时需要时间,但从长远来看会有所回报。

If you can pass in the IDbSet into your repository that it is querying, you can easily write your own stub implementation of IDbSet that reads from and writes to an in-memory collection mapped to an IQueryable , or use a mocking framework to do it for you.如果您可以将IDbSet传递到它正在查询的存储库中,您可以轻松编写自己的IDbSet存根实现,该存根实现读取和写入映射到IQueryable的内存中集合,或者使用 mocking 框架来执行此操作你。

In your production code, you pass in the IDbSet from the real DbContext ;在您的生产代码中,您从真实的DbContext IDbSet in your test code, you pass in this stub.在您的测试代码中,您通过了这个存根。

If your repository under test references the DbContext then you may want to refactor so that it only references an individual IDbSet .如果您正在测试的存储库引用了DbContext ,那么您可能需要重构以使其仅引用单个IDbSet

I assume that you just don't want to have to load/save any entities within your test (ie: test only your business logic, not the persistence layer).我假设您只是不想在测试中加载/保存任何实体(即:仅测试您的业务逻辑,而不是持久层)。 In that case you will need a way to easily generate (and re-use) test 'stubs'.在这种情况下,您将需要一种方法来轻松生成(和重用)测试“存根”。 Simplest way imo is to create some factories for your various entities that return some simple(but meaningful) entities. imo 最简单的方法是为您的各种实体创建一些工厂,这些工厂返回一些简单(但有意义)的实体。

For instance, if you were testing your User engine, you might want to have a testing factory that generates users of different types, maybe a User from Wisconsin, or a user with a VERY long last name, or a user with no friends, vs. a user with 100 friends, etc.例如,如果您正在测试您的用户引擎,您可能希望有一个测试工厂来生成不同类型的用户,可能是威斯康星州的用户,或者姓氏很长的用户,或者没有朋友的用户,vs . 一个有 100 个朋友的用户,等等。

public static class UserStubFactory {
    static User NewUserWithLongLastName(int letterCount) {  //return user with long last name  }
    static User NewUserWithXFriends(int count) { //return user w/ X friends }
}

Then when you generate other test stub factories, you can start chaining them together.然后,当您生成其他测试存根工厂时,您可以开始将它们链接在一起。 So maybe you'd want to test a User with a long last name, and then put them through some other actions within your system.因此,也许您想测试一个姓氏很长的用户,然后让他们在您的系统中执行一些其他操作。 Well now you already have the TestStub so you can simply call NewUserWithLongLastName() and pass him thru your engine.现在你已经有了 TestStub,所以你可以简单地调用 NewUserWithLongLastName() 并将他传递给你的引擎。

If you're not of this method you can also just create them on the fly with the constructor syntax.如果您不使用此方法,您也可以使用构造函数语法即时创建它们。

User newUser = new User() {  LastName ="HOLYCOWTHISISAVERYYLONGLASTNAME"; }

but I prefer the factories for their re-usability factor.但我更喜欢工厂,因为它们的可重用性因素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM