【问题标题】:How to Unit test the following method?如何对以下方法进行单元测试?
【发布时间】:2012-12-03 09:00:51
【问题描述】:
public User AddTags(int userId, List<Tag> Tags)
            {
                var user = GetUserById(userId);
                Tags.ForEach( tag => user.Tags.Add(tag));
                return _repository.Update(user);
            }
public interface IRepository<T> where T:class 
    {
        void Add(T item);
        void Remove(T item);
        T Update(T item);
    }

在测试类中

protected IRepository<User> Repository;
protected UserService Service;
public Mock<IRepository<User>> MockUserRepository = new Mock<IRepository<User>>();
Repository = MockUserRepository.Object;
Service = new UserService(UnitOfWork, Repository);
//I don't quite understand how to mock the Update method.
var result = Service.AddUserTags(1,Tags);
Assert.AreEqual(result.UserTags.Count(),3);

我有一个List&lt;User&gt; users 和一个List&lt;Tag&gt; tags

我正在使用 EF、NUnit、MOQ 和通用存储库模式。

编辑:

在 GetUserById 中

return _repository.GetAll().Where(_ => _.UserId == userId).SingleOrDefault();

I have mocked it doing the following 

MockUserRepository.Setup(_ => _.GetAll()).Returns(Users.AsQueryable());

【问题讨论】:

    标签: c# entity-framework unit-testing nunit moq


    【解决方案1】:

    我取决于GetUserById(userId); 中发生的事情。为了检查UserTags 的计数,您必须通过模拟GetUserId 来控制返回的User

    否则,您能做的最好的事情就是确保调用Update 方法:

    repository.Verify(x => x.Update(It.IsAny<User>()));
    

    编辑后: 然后,您需要设置用户:

    [TestFixture]
        public class TestPointer
        {
            private IRepository<User> Repository;
            private UserService Service;
            private Mock<IRepository<User>> MockUserRepository = new Mock<IRepository<User>>();
    
            [Test]
            public void GetItemsByUserName_UserName_ListOfItems()
            {
                //Arrange
                var unitOfWork = new UnitOfWork();
                Service = new UserService(unitOfWork,  MockUserRepository.Object);
                var Tags = new List<Tag>() { new Tag { Name = "TestTag1" }, new Tag { Name = "TestTag2" }, new Tag { Name = "TestTag3" } };
                var user = new User() {Id = 1};
                MockUserRepository.Setup(x => x.Find(1)).Returns(user);
                MockUserRepository.Setup(x => x.Update(user)).Returns(user);
    
                //Act
                var result = Service.AddTags(1, Tags);
    
    
                //Assert
                Assert.AreEqual(result.Tags.Count(),3);
            }
        }
    
        public class UserService
        {
            private IRepository<User> _repository;
            private UnitOfWork _unitOfWork;
    
            public UserService(UnitOfWork unitOfWork, IRepository<User> repository)
            {
                _unitOfWork = unitOfWork;
                _repository = repository;
            }
    
            public User AddTags(int userId, List<Tag> Tags)
            {
                var user = GetUserById(userId);
                Tags.ForEach(tag => user.Tags.Add(tag));
                return _repository.Update(user);
            }
    
            private User GetUserById(int userId)
            {
                return _repository.Find(userId);
            }
        }
    
        public class UnitOfWork
        {
    
        }
    
        public interface IRepository<T> where T:class
        {
            T Find(int id);
            void Add(T item);
            void Remove(T item);
            T Update(T item);
        }
    
        public class User
        {
            private List<Tag> tags = new List<Tag>();
    
            public int Id { get; set; }
            public List<Tag> Tags
            {
                get { return tags; }
                set { tags = value; }
            }
        }
    
        public class Tag
        {
            public string Name { get; set; }
        }
    

    【讨论】:

    • 添加标签后计数不应该是 4,似乎没有真正的更新发生吗?
    • 你是怎么得到 4 的?我要添加 3 个标签,是吗?而且,没有真正的更新发生,因为我们正在模拟存储库。
    【解决方案2】:

    如果你想断言用户发生了什么,应该注入 GetuserById 方法,这样它就可以被一个模拟替换,返回一个模拟用户。然后,您可以验证 user.Tags.Add(tag) 的调用次数是否正确。

    之后,可以验证_repository.Update(user)被调用了一次;

    对于 Moq 中的非常化语法,请查看 this 链接。

    【讨论】:

    • 我应该检查正确的通话次数吗?如果我遍历列表,那么除了检查空值之外,这种 Assert 的目的是什么?
    • 它会验证循环中的逻辑是否正确,所以我会这么说,尽管逻辑很简单。
    猜你喜欢
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多