1

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

我有一个 Manager 类,有一个方法 say AddCat(string name);。该方法确保name是有效的,并调用AddCat(string name)我的CatRepository. CatRepository正义的myContext.Cats.Add(new Cat() { Name = name });

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

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

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

4

1 回答 1

5

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

您应该单独测试每个类。您的 Manager 类包含实际的业务逻辑,因此您可能想要测试几个场景:

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

您要确保CatRepository.Add在名称无效时不调用它,并且在有效时使用正确的名称调用它。要实现这一点,请确保您的Manager类与接口一起使用ICatRepository。在您的单元测试中,您使用一种称为模拟的技术将ICatRepository的假实现传递给您的 Manager 类。模拟具有特殊功能,可让您检查调用了哪些方法并验证这些方法的参数。

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

// Not a good solution
public class Manager
{
    public Manager()
    {
        this.catRepository = new CatRepository();
    }
}

这样你就无法CatRepository用你的模拟版本替换。相反,您应该使用一种称为依赖注入的方法:

 // Seperate construction from business logic
 public class Manager
 {
     public Manager(ICatRepository catRepository)
     {
         this.catRepository = catRepository;
     }
 }

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

大约一年前,我写了一篇关于这个主题的博客,解释了集成和单元测试之间的区别,以及模拟如何帮助你创建好的单元测试:单元测试,地狱还是天堂?

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

您的上下文生成为partial class. 部分意味着您的课程可以分布在多个 .cs 文件中。编译器将这些文件合并在一起并为其输出一个类。这样,您可以拥有一个由 EF 自动生成的 .cs 文件和另一个实现您的接口的文件。像这样的东西:

我的上下文.cs

public partial class MyContext : ObjectContext
{ }

我的上下文接口.cs

public interface IMyContext {}

public partial class MyContext : IMyContext
{ }
于 2013-05-06T10:22:41.497 回答