关于模拟EF 5和测试存储库模式的一些问题

时间:2013-05-06 10:11:22

标签: c# entity-framework unit-testing

我一直在阅读一些关于模拟我的存储库模式EF 5的文章,我对一些事情感到困惑:

我有一个Manager类,方法是AddCat(string name);。该方法可确保name有效,并在AddCat(string name)上调用CatRepositoryCatRepository仅执行myContext.Cats.Add(new Cat() { Name = name });

我相信简而言之就是存储库模式。

  • 我应该将存储库传递给Manager类,以便稍后对其进行单元测试,还是应该只测试存储库?

  • 我想将一个上下文传递到我的存储库中,以便对其进行单元测试。所以我创建了一个接口IMyContext,但我不确定如何获得EF上下文来实现它 - 因为我添加它的地方是自动生成的代码,我担心它会擦除它。是否有其他方法可以让我将自定义上下文传递给存储库?

1 个答案:

答案 0 :(得分:5)

  

我应该将存储库传递给Manager类,以便稍后使用   单元测试它,还是我应该只测试存储库?

您应该单独测试每个类。您的Manager类包含实际的业务逻辑,因此您可能希望测试几个方案:

  • 有效名称
  • 名称无效
  • 空名称

您希望确保在名称无效时未调用CatRepository.Add,并且在名称无效时使用正确的名称调用Manager。为此,请确保ICatRepository类适用于接口// Not a good solution public class Manager { public Manager() { this.catRepository = new CatRepository(); } } 。在单元测试中,您使用一种名为mocking的技术将ICatRepository的伪实现传递给Manager类。模拟具有特殊功能,可以让您检查调用哪些方法并验证这些方法的参数。

这意味着您的经理不应自己构建CatRepository:

CatRepository

这样您无法用模拟版本替换 // Seperate construction from business logic public class Manager { public Manager(ICatRepository catRepository) { this.catRepository = catRepository; } } 。相反,您应该使用一个名为Dependency Injection的方法:

CatRepository

您的partial class不包含任何实际逻辑。您可以使用集成测试(使用真实数据库或其他外部对象的较慢运行测试)来确保您的存储库正常运行。

我在一年前写了一篇关于这个主题的博客,解释了集成和单元测试之间的区别,以及模拟可以帮助你创建好的单元测试:Unit Testing, hell or heaven?

  

我想将一个上下文传递到我的存储库中,以便对其进行单元测试。所以   我创建了一个接口IMyContext,但我不知道如何获得EF   实现它的上下文 - 因为我添加它的地方是自动生成的   代码,我担心它会擦掉它。还有其他方法可以让   我将自定义上下文传递给存储库?

您的上下文生成为public partial class MyContext : ObjectContext { } Partial表示您的班级可以分布在多个.cs文件中。编译器将这些文件合并在一起并为其输出一个单独的类。这样,您可以拥有一个由EF自动生成的.cs文件和另一个实现您的界面的文件。像这样:

mycontext.cs

public interface IMyContext {}

public partial class MyContext : IMyContext
{ }

mycontextinterface.cs

{{1}}