我如何让这个模拟工作?

时间:2015-11-25 07:46:31

标签: c# unit-testing mocking moq

我需要对没有测试的遗留类进行更改,所以我已经开始编写测试,但是模拟(使用Moq)无法正常工作。

这是我的测试

[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);
}

内部LightningMapLocationsHelper是以下方法

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;
}

当被调用时使用GroupRepository的实际实例而不是测试中设置的groupRepo模拟,从而导致测试失败。当GroupRepository实现IGroupRepository时,我希望这会有效。

public class GroupRepository : IGroupRepository {…}

也许我误解了嘲讽是如何运作的。有人可以提供一些见解,帮助我理解为什么这不起作用,以及我如何解决它?我是否必须传递模拟类?

0 个答案:

没有答案