我一直在阅读一些关于模拟我的存储库模式EF 5的文章,我对一些事情感到困惑:
我有一个Manager类,方法是AddCat(string name);
。该方法可确保name
有效,并在AddCat(string name)
上调用CatRepository
。 CatRepository
仅执行myContext.Cats.Add(new Cat() { Name = name });
我相信简而言之就是存储库模式。
我应该将存储库传递给Manager类,以便稍后对其进行单元测试,还是应该只测试存储库?
我想将一个上下文传递到我的存储库中,以便对其进行单元测试。所以我创建了一个接口IMyContext
,但我不确定如何获得EF上下文来实现它 - 因为我添加它的地方是自动生成的代码,我担心它会擦除它。是否有其他方法可以让我将自定义上下文传递给存储库?
答案 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}}