2012-09-20 23 views
0

我想了解一种创建实现存储库接口的MockRepository的方法。目前,这是我所:来自接口的Moq MockRepository

public class MockUserRepository 
    { 
     private readonly IList<User> _users; 

     public MockUserRepository() 
     { 
      _users = new List<User>() 
         { 
          new User() 
           { 
            UserId = new Guid("E480E40F-6802-4296-B2A8-E0D5E018CD41"), 
            Username = "admin", 
            Password = "5A105E8B9D40E1329780D62EA2265D8A", 
            CellPhone = "3175172957" 
           } 
         }; 
     } 

     public IUserRepository Create() 
     { 
      var mockUserRepository = new Mock<IUserRepository>(); 

      mockUserRepository.Setup(m => m.Count()).Returns(_users.Count()); 

      mockUserRepository.Setup(m => m.Get()).Returns(_users); 

      mockUserRepository.Setup(m => m.Get(It.IsAny<Guid>())).Returns((Guid id) => _users.First(x => x.UserId == id)); 

      mockUserRepository.Setup(m => m.Save(It.IsAny<User>())).Returns(
       (User user) => 
        { 
         var now = DateTime.Now; 

         user.ModifiedOn = now; 

         if(user.UserId.Equals(Guid.Empty)) 
         { 
          user.CreatedOn = now; 
          _users.Add(user); 
         } 
         else 
         { 
          var original = _users.First(x => x.UserId == user.UserId); 
          if (original == null) 
          { 
           return false; 
          } 

          original = user; 
         } 
         return true; 
        } 
       ); 

      mockUserRepository.Setup(m => m.Find(It.IsAny<IList<object[]>>())).Returns(
       (IList<object[]> criteria) => 
       { 
        IList<User> uList = _users.ToList(); 

        foreach (object[] criteriaItem in criteria) 
        { 
         var name = (string)criteriaItem[0]; 
         var value = (string)criteriaItem[1]; 
         IList<User> tempList = uList.ToList(); 
         IList<User> addList = tempList.Where(user => (string) user.GetType().GetProperty(name).GetValue(user, null) == value).ToList(); 
         uList = addList; 
        } 
        return uList; 
       }); 

      return mockUserRepository.Object; 
     } 
    } 

我想有这样的事情:

public class MockUserRepository : IUserRepository 

然后,就拥有所有的实际执行我的嘲笑方法。我想这样做是为了强制我的开发人员根据接口完全模拟一个存储库。

从测试方面,这款嘲笑存储库这样使用:

[SetUp] 
    public void Setup() 
    { 
     MockUserRepository = new MockUserRepository().Create(); 
     MockRoleRepository = new MockRoleRepository().Create(); 
     MockQuestionRepository = new MockQuestionRepository().Create(); 

     AuthenticationService = new AuthenticationService(MockUserRepository, MockRoleRepository, MockQuestionRepository); 
    } 

所有这一切都工作得很好,但我真的停留在执行我的MockRepository来实现它的所有接口的方法。

回答

2

这是过度复杂的使用模拟。只需在测试中模拟IUserRepository接口,然后根据测试嘲笑您需要的方法。

reposistory = new Mock<IUserRepository>(); 

var id = 1; 
var user = new User(); 
repository.Setup(x=> x.Get(id)).Returns(user); 

var sut = new Service(repository.Object); 
var result = sut.Get(id); 

Assert.Equals(user, result); 

如果你真的想要一个“空白”的对象只实现一个假IUserRepository和完全放弃一个模拟框架。

class FakeUserRepository : IUserRepository 
{ 
    public List<User> Users = new List<Users>(); 

    public User Get(long id) 
    { 
     return Users.FristOrDetail(x=>x.Id = id); 
    } 
} 

var id = 1; 
var user = new User(); 
var repository = new FakeUserRepository(); 
repository.Users.Add(user); 

var sut = new Service(repository); 
var result = sut.Get(id); 

Assert.Equals(user, result);  
+0

我真的过分复杂吗?我正在考虑我将至少有10项服务,每项服务将使用1个或多个存储库,并且大多数存储库将被多项服务使用。例如,AuthenticationService并且说EventService可能使用UserRepository。在你的例子中,我会多次写同一个Setup。现在,你应该知道,我是一名程序员,所以我很懒。为什么我不想只写一次Setups?我仍然对强制开发人员实现所有存储库接口的方法感到好奇。 –

+0

你想要的是一个存根,而不是假的。实现一个具体的类并提供获取和设置所需值的钩子。我会用一个简单的假冒来更新我的答案 –

+0

你帮我看到了灯!我过于复杂的一切。我决定现在不要使用Moq,而是要创建FakeRepositories。我可能会在未来的某个时候回到Moq,但现在,假装会为我工作。谢谢! –