2011-10-13 84 views
1

快速信息:我使用C#4.0和RhinoMocks(AAA级)假DataRepository - 模拟数据库

我会用一些代码什么,我想这样做解释:

public class SampleData 
{ 
    private List<Person> _persons = new List<Person>() 
    { 
     new Person { PersonID = 1, Name = "Jack"}, 
     new Person { PersonID = 2, Name = "John"} 
    }; 

    public List<Person> Persons 
    { 
     get { return _persons; } 
    } 
} 

所以这是一个类模仿数据库中的数据。现在我想在我的单元测试中使用这些数据。换句话说,我不想从数据库中获取数据,而是想将它们从数据源中取出。

我想我可以通过测试框架的存储库,并通过使用DataRepository,而不是实现这一目标:

UC1003_ConsultantsBeherenBL consultantsBeherenBL = new UC1003_ConsultantsBeherenBL(); 

consultantsBeherenBL = MockRepository.GeneratePartialMock<UC1003_ConsultantsBeherenBL>(); 
consultantsBeherenBL.Repository = MockRepository.GenerateMock<IRepository>(); 

这将导致我的代码,以全自动寻找在DataRepository,而不是数据。所以不是直接插入一个方法,而是直接插入一个列表(例如d => d.Find(Arg.Is.Anything))。IgnoreArguments()。Return(你刚填好的列表))我会得到“真正的”数据返回(从DataRepository中过滤的数据)。这意味着我可以测试我的代码是否可以真正找到某些东西,而无需在我的数据库中插入测试数据(集成测试)。

我该如何去实现这样的事情?我试过在网上查找文章或问题,但我似乎找不到很多:/

任何帮助表示赞赏。

编辑:我试过SimpleInjector和StructureMap,但我坚持实现其中之一。目前我使用我的实体框架的存储库

,所以我baseBL看起来像这样(注:我的所有其他BL的enherit从这个):

public class BaseBL 
{ 
    private IRepository _repository; 

    public IRepository Repository 
    { 
     get 
     { 
      if (_repository == null) 
       _repository = new Repository(new DetacheringenEntities()); 
      return _repository; 
     } 
     set { _repository = value; } 
    } 

    public IEnumerable<T> GetAll<T>() 
    { 
    ... --> Generic methods 

我的仓库类:

public class Repository : BaseRepository, IRepository 
{ 
    #region Base Implementation 

    private bool _disposed; 

    public Repository(DetacheringenEntities context) 
    { 
     this._context = context; 
     this._contextReused = true; 
    } 

    #endregion 

    #region IRepository Members 

    public int Add<T>(T entity) 
    ... --> implementations of generic methods 

据我所知,我现在需要能够在我的测试中说,而不是使用DetacheringenEntities,我需要使用我的DataRepository。我不明白我是如何用数据类切换出我的实体框架的,因为那个数据类不适合那里。

我应该让我的DataRepository使我的IRepository类成为我自己的实现吗?

public class SampleData : IRepository 

但我不能做这样的事情与我的列表:再次求助/

public IEnumerable<T> GetAll<T>() 
    { 
     return Repository.GetAll<T>(); 
    } 

非常感谢

编辑:我意识到,单元测试不需要一个数据存储库,所以我只是在集成测试中测试这个逻辑。这使得数据库无用,因为代码可以在没有存储库的情况下进行测试。 我想感谢大家的帮助,谢谢:)

+0

查看[本文](http://www.cuttingedge.it/blogs/steven /pivot/entry.php?id=84)。 – Steven

+0

你想要测试什么? –

+0

好吧,这不仅仅是一次测试,而是我想要设置的,所以我可以运行多个测试,并且不会耗费我的数据库。在这种情况下,我想测试一个搜索功能,在我的FakeDataRepository中有多个人。当我调用需要测试的方法时,我希望方法使用FakeDataRepository作为源,因此它可以过滤出正确的人员。 –

回答

4

使用Dependency injection framework来处理您的依赖关系。在你的单元测试中,你可以将真正的实现与一个残缺的实现交换。

在StructureMap中,例如,你会在你的代码中说。“好吧,现在给我一个IDataRepository的活动实例”,对于您的普通代码,这将指向实际数据库的实现。在你的单元测试中,你可以通过把ObjectFactory.Inject(new FakeDataRepository())覆盖。假回购随后被所有代码使用,这使得测试单个工作单元变得非常简单.i

+0

嘿,谢谢你的回答。我将尝试实施它(4.0版)。我会告诉你,如果它的工作,因为它肯定听起来像我需要的东西:) –

+0

我在我的问题中添加了新的部分,因为我有一些问题实现它。 –