有没有更好的方法来使用泛型初始化模拟的存储库?

时间:2011-02-14 01:10:54

标签: c# moq generics

我正在尝试找到一种为我的测试类初始化模拟存储库的通用方法。由于我有多个存储库,我尝试使用泛型。我有一个通用的存储库接口:

public interface IRepository<T> where T: class
{
    IQueryable<T> GetAll();
}

我的静态初始化方法如下所示:

public static Mock<T> GetRepository<T, TK>(params TK[] items) where T: class, IRepository<TK> where TK: class 
{
    Mock<T> mock = new Mock<T>();
    mock.Setup(m => m.GetAll()).Returns(items.ToList().AsQueryable);
    return mock;
} 

要在我使用的代码中初始化我的存储库:

Mock<IRepository<Link>> linkRepository = UnitTestHelpers.GetRepository<IRepository<Link>, Link>(new[] { 
   new Link { LinkId = 1, Title = "Title 1", Created = DateTime.Now, Url = "http://google.com" }, 
   new Link { LinkId = 1, Title = "Title 2", Created = DateTime.Now, Url = "http://google.com" }, 
   new Link { LinkId = 1, Title = "Title 3", Created = DateTime.Now, Url = "http://google.com" } 
});

我觉得这不是最优雅的方式,因为我必须在GetRepository方法中指定两次Link。有没有更好/更清洁的方法呢?

1 个答案:

答案 0 :(得分:1)

是的,有一种更顺畅的方法来实现这一目标。正如您所提到的,Link类型参数是多余的,这是因为没有必要对通用IRepository<T>类型进行参数化。试试这个

public static Mock<IRepository<T>> GetRepository<T>(params T[] items) where T: class {
    Mock<IRepository<T>> mock = new Mock<IRepository<T>>();
    mock.Setup(m => m.GetAll()).Returns(items.ToList().AsQueryable);
    return mock;
}

一些不相关的提示:

  • 除非确实如此,否则请暂停ToList()来电 需要。增加了懒惰和提高了可读性。
  • 使用特定的DateTime而不是DateTime.Now来创建repeatable单元测试。