mardi 24 novembre 2015

How do I get this mock to work?

I need to make changes to a legacy class with no tests so I have started by writing a test, however the mocking (using Moq) isn't working properly.

This my test

[Test]
public void CorrectlyCopiesToLightningWhenNoLocationsExist()
{
  // arrange
  long orgId = Id64.NewId();
  var data = LightningMapLocationsHelperTestData.ForNormalCopy(orgId);

  var organisation = new Group
  {
    GroupId = orgId,
    Name = "Test Organisation",
    Type = GroupType.OrganisationGroup
  };

  var groupRepo = new Mock<IGroupRepository>();
  groupRepo.Setup(r => r.GetGroup(orgId)).Returns(organisation);

  var orgRepo = Mock.Of<IOrganisationRepository>(o => o.LightningLocationsEnabledFor(orgId));

  var mapLocationRepo = new Mock<IMapLocationRepository>();
  mapLocationRepo.Setup(r => r.OrganisationRepository).Returns(orgRepo);
  mapLocationRepo
    .Setup(r => r.GetMapLocationsByGroupIds(orgId, It.IsAny<IEnumerable<long>>(), true, true))
    .Returns(data.InitialDatabaseLocations);

  var lightningMapLocationRepo = new Mock<ILightningMapLocationRepository>();
  lightningMapLocationRepo
    .Setup(r => r.LocationsById(orgId, data.InitialLightningLocations.Select(l => l.LocationId)))
    .Returns(data.InitialLightningLocations);
  lightningMapLocationRepo
    .Setup(r => r.AddLocations(It.IsAny<List<Location>>()))
    .Callback((List<Location> locations) => data.InitialLightningLocations.AddRange(locations));

  var infoMessages = new List<string>();
  var errorMessages = new List<string>();

  var helper = new LightningMapLocationsHelper(
    (string s, object[] args) => infoMessages.Add(string.Format(s, args)),
    (string s, object[] args) => errorMessages.Add(string.Format(s, args)));

  List<CopyFailure> copyFailures;

  // act
  bool success = helper.CopyLocationsForOrganisation(orgId, 10, out copyFailures);

  // assert
  success.ShouldBeTrue();
  (errorMessages?.Count ?? 0).ShouldBe(0);
  data.InitialLightningLocations.Count.ShouldBe(data.ExpectedLightningLocations.Count);
}

Inside LightningMapLocationsHelper is the following method

private Group GetValidOrganisationGroup(long groupId)
{
  var organisation = (new GroupRepository()).GetGroup(groupId);
  if (organisation != null && organisation.Type == GroupType.OrganisationGroup) return organisation;

  LogErrorMessage("Invalid groupId: {0}. Ignoring...", groupId);
  return null;
}

that when called is using an actual instance of GroupRepository rather than the groupRepo mock set up in the test, thus causing the test to fail. As GroupRepository implements IGroupRepository I expected this to work.

public class GroupRepository : IGroupRepository {…}

Perhaps I am misunderstanding how mocking works. Can someone offer some insight to help me understand why this doesn't work, and how I can fix it? Do I have to pass the mocked classes in?

Aucun commentaire:

Enregistrer un commentaire