Reputation: 2269
I've created a method called ListOfPeople
and trying to write a Unit Test for it. Currently, I am having trouble setting up the Arrange
section of my Unit Test. I can't run it right now because my PeopleId
and PersonGroupJobId
states Cannot resolve symbol
.
Question: How can I test this method successfully?
My Method:
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;
}
Unit Test:
[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());
}
Upvotes: 2
Views: 2961
Reputation: 107247
You aren't using Moq's
It
matchers correctly. Matchers are intended for use in Moq's Setup
and Verify
calls (e.g. see here for example usage)
It.IsAny
when creating fake data. All that will happen with It.IsAny<>
is that the values will be assigned default(Type)
, i.e. zero for Ints etc, which isn't going to be useful.var people = new List<DB.Person>
{
new DB.Person
{
PeopleId = 1234, // Some traceable value and NOT It.IsAny<int>(),
PersonGroupdJobId = 987,
...
It.IsAny<>
):var result = _repository.ListOfPeople(1234, 567); // Filters matching your test scenario
Also, since the method being tested has at least two concerns, viz applying a filter to the repository, and then mapping out a DB entity to another POCO, you need to provide a complete set of input data so that you can prove that all input fields are mapped to output fields.
If you put all this together, your unit test will look something like:
[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());
}
Upvotes: 3
Reputation: 43254
You aren't initialising your list properly. You need:
var people = new List<DB.Person>
{
new DB.Person
{
PeopleId = It.IsAny<int>(),
PersonGroupdJobId = It.IsAny<int>()
}
};
Upvotes: 3