使用Moq安排单元测试

时间:2015-07-15 14:15:48

标签: c# asp.net unit-testing moq

我创建了一个名为ListOfPeople的方法,并尝试为其编写单元测试。目前,我在设置单元测试Arrange部分时遇到问题。我现在无法运行它,因为我的PeopleIdPersonGroupJobId状态Cannot resolve symbol

  

问题: 如何成功测试此方法?

我的方法:

public IEnumerable<Person> ListOfPeople(int personId, int? jobId)
        {
            var people = _unitOfWork.GetRepository<DB.Person>().GetAll()
              .Where(p => p.PeopleGroups.Any(m => m.PeopleId == personId 
                              && m.PersonGroupdJobId == jobId));

            if (!people.Any())
                return new List<Person>();

            var personData = people.Select(p => new Person
            {
                Id = p.PersonId,
                Name = p.PersonName,
                WorkTypeId = p.WorkTypeId,
                PrimaryLanguage = p.PrimaryLanguage,
                PeopleGroups = p.PeopleGroups.ToList()
                  .Select(pp => new PeopleGroup
                  {
                      Id = pp.ProjectPartyId,
                      PeopleId = pp.PeopleId,
                      JobId = pp.PersonGroupJobId ?? 0,
                      AddressId = pp.AddressId
                  })
            }).ToList();

            return personData;
        }

单元测试:

[TestMethod]
    public void ListOfPeople_peopleExist_returnsList()
    {
        // Arrange
        var people = new List<DB.Person>
        {    
            PeopleId = It.IsAny<int>(),
            PersonGroupdJobId = It.IsAny<int>()
        }; 

        _uowMock
            .Setup(mock => mock.GetRepository<DB.Person>().GetAll())
            .Returns(people.AsQueryable());

        // Act
        var result = _repository.ListOfPeople(It.IsAny<int>(), It.IsAny<int>());

        // Assert
        Assert.IsNotNull(result);
        Assert.AreEqual(2, result.Count());

        _unitOfWork.Verify(mock => mock.Commit(), Times.Never());
        _unitOfWork.Verify(mock => mock.GetRepository<DB.Person>().GetAll(), Times.Once());
    }

2 个答案:

答案 0 :(得分:3)

您无法正确初始化列表。你需要:

var people = new List<DB.Person>
{
    new DB.Person
    {    
        PeopleId = It.IsAny<int>(),
        PersonGroupdJobId = It.IsAny<int>()
    }
};

答案 1 :(得分:3)

您没有正确使用It Setup匹配器。匹配器旨在用于Moq的VerifyIt.IsAny电话(例如see here用途)

  • 在安排中,您在创建虚假数据时不应使用It.IsAny<>default(Type)所发生的一切就是价值将被分配var people = new List<DB.Person> { new DB.Person { PeopleId = 1234, // Some traceable value and NOT It.IsAny<int>(), PersonGroupdJobId = 987, ... ,即Ints等为零,这不会有用。

It.IsAny<>
  • 在行动步骤中,您需要使用执行方案的值调用测试中的方法(同样,不仅仅是var result = _repository.ListOfPeople(1234, 567); // Filters matching your test scenario ):

[Test]
public void ListOfPeople_peopleExist_returnsList()
{
    // Arrange : Generate fake data
    var people = new List<DB.Person>
    {    
        new DB.Person
        {
            PersonId = 123,
            PersonName = "Bob",
            PrimaryLanguage = "French",
            WorkTypeId = 987,
            PeopleGroups = new []
            {
                new DB.PeopleGroup
                {
                    AddressId = 123,
                    PersonGroupJobId = 999,
                    PeopleId = 123, // Match the parent ID
                    ProjectPartyId = 3
                }
            }
        }
    };

    // Your _unitOfWork and _repository mocks seem to be class private fields
    var _unitOfWork = new Mock<IUnitOfWork>();

    _unitOfWork
        .Setup(mock => mock.GetRepository<DB.Person>().GetAll())
        .Returns(people.AsQueryable());

    var _repository = new MyRepo(_unitOfWork.Object);

    // Act
    var result = _repository.ListOfPeople(123, 999);

    // Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(1, result.Count(r => r.Name == "Bob" 
                                         && r.Id == 123 
                                         && r.PeopleGroups.First().Id == 3));
  //... etc - ensure all the fields are mapped 

    _unitOfWork.Verify(mock => mock.Commit(), Times.Never());
    _unitOfWork.Verify(mock => mock.GetRepository<DB.Person>().GetAll(), 
                       Times.Once());
}

此外,由于正在测试的方法至少有两个问题,即将过滤器应用于存储库,然后将数据库实体映射到另一个POCO,您需要提供一整套输入数据,以便您可以证明所有输入字段都映射到输出字段。

如果将所有这些放在一起,您的单元测试将类似于:

chart.draw(data, options)