开发者

Is there a better way to initialize a mocked repository using generics?

I am trying to find a generic way of initializing a mock repository for my test class. As I have multiple repositories I tried doing it using generics. I have a generic repository interface:

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

My static initialization method looks like this:

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;
} 

To initialize my repository in code I use:

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" } 
});

I feel this is not the most elegant way开发者_运维知识库 of doing this as I have to specify Link twice in the GetRepository method. Is there a nicer/cleaner way of doing this?


Yes, there is a somewhat smoother way to achieve this. As you mention the Link type parameter is redundant, this is because there is no real need to parametrize the generic IRepository<T> type. Try this

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;
}

Some unrelated hints:

  • Drop the ToList() call unless really needed. Adds lazyness and improved readability.
  • Use a specific DateTime rather than DateTime.Now to create a repeatable unit-test.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜