【问题标题】:How to verify number of calls method of 'this' service如何验证“此”服务的调用次数方法
【发布时间】:2015-04-22 09:15:24
【问题描述】:

我正在使用带有最小起订量的 NUnit 框架进行测试。我对调用此类的私有方法的次数有疑问。要使用模拟对象执行此操作,只需使用 Times 类型的参数调用 Verify() 就足够了,但我的方法是此类的一部分。我试图模拟当前服务 (SUT),但这可能不是最好的主意,而且它不能正常工作。

SUT:

public object Post(Operations.Campaign.Merge request)
{
    List<CampaignIdWithNumberOfAds> campaignList = new List<CampaignIdWithNumberOfAds>();

        for (int i = 0; i < request.CampaignIdsToMerge.Count; i++)
        {
            if (this.CampaignRepository.Exist(request.CampaignIdsToMerge[i]))
            {
                campaignList.Add(new CampaignIdWithNumberOfAds()
                {
                    CampaignId = request.CampaignIdsToMerge[i],
                    NumberOfAdvertisement = this.CampaignRepository.GetNumberOfAdvertisementsInCampaign(request.CampaignIdsToMerge[i])
                });
            }
        }

        if (campaignList.Count > 1)
        {
            campaignList = campaignList.OrderByDescending(p => (p == null) ? -1 : p.NumberOfAdvertisement).ToList();
            List<CampaignIdWithNumberOfAds> campaignsToMerge = campaignList.Skip(1).ToList();
            CampaignIdWithNumberOfAds chosenCampaign = campaignList.FirstOrDefault<CampaignIdWithNumberOfAds>();

            uint chosenCampaignId = chosenCampaign.CampaignId;

            foreach (var campaignToMerge in campaignsToMerge)
            {
                this.MergeCampaigns(chosenCampaignId, campaignToMerge.CampaignId);
            }
        }

        return true;
    }

测试:

    [Test]
    public void MergeCampaignsPost_ValidMergeCampaignsRequest_ExecuteMergeCampaignsMethodAppropriateNumberOfTimes() 
    {
        // Arrange
        var mockCampaignService = new Mock<Toucan.Api.Services.CampaignService>();
        var request = Mother.GetValidMergeCampaignsRequest_WithDifferentNumbersOfAdvertisement();
        mockCampaignService.Setup(x => x.MergeCampaigns(It.IsAny<uint>(), It.IsAny<uint>()));

        // Act
        var response = this.Service.Post(request);

        // Assert
        mockCampaignService.Verify(x => x.MergeCampaigns(It.IsAny<uint>(), It.IsAny<uint>()), Times.Exactly(request.CampaignIdsToMerge.Count - 1));
    }

【问题讨论】:

    标签: c# unit-testing nunit moq


    【解决方案1】:

    恐怕我不会在这里给你一个解决方案,尽管我宁愿给你一些指导。单元测试有许多不同的策略,不同的人会提出不同的解决方案。基本上,在我看来,您可以更改测试代码的方式(您可能同意或不同意这些,但请考虑到它们)。


    • 单元测试应该独立于实现

    听起来很简单,但要坚持这种方法非常困难。私有方法是您解决问题的实现。开发人员为自己的代码编写单元测试的典型陷阱是,您知道代码如何工作并在单元测试中反映它。如果实现发生变化,但公共方法仍将履行请求的合同怎么办?您几乎不想使用私有方法直接进行单元测试。这与以下有关...

    • 测试应该检查方法的输出结果

    这基本上意味着如果您不需要,请不要检查执行了多少次。我不确定您的 MergeCampaigns 方法在做什么,但是如果您检查操作的结果而不是执行多少次会更好。

    • 不要过度进行单元测试 - 保持可维护性

    尝试使用尽可能简单和独立的测试来测试您可以想象的每个功能场景。不要太深入地检查是否调用了某些东西。否则,您将在开始时获得 100% 的覆盖率,但每次更改服务中的内容时您都会诅咒,因为这会使您的一半测试失败(假设服务仍在执行其工作,但方式不同开始设计)。因此,您将花时间重写单元测试,这些单元测试在创建防弹解决方案方面实际上并没有给您带来任何好处。


    开始编写单元测试并保持绿色覆盖非常容易,如果你想编写好的单元测试,它开始变得非常棘手。有很多有价值的资源可以帮助你。祝你好运!

    【讨论】:

      猜你喜欢
      • 2018-05-21
      • 2021-11-21
      • 2015-11-19
      • 2013-01-31
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多