使用 Moq 进行单元测试,但对象返回 Null

本文关键字:对象 返回 Null 单元测试 Moq 使用 | 更新日期: 2023-09-27 18:31:11

我是使用最小起订量新手。 我正在尝试让这个单元测试工作,但我的对象似乎一直返回 null。 我在网上看到 Setup() 必须与实际调用匹配。 我显然没有得到它,因为它仍然不起作用;它似乎与我匹配。 这是我的代码示例。

测试

项目的测试方法:

    [TestMethod]
    public void CanPutEmailOptOut()
    {
        var mockParticipant = new PscuParticipant
            {
                ParticipantId = 1,
                DoNotSendCuRewardsEmails = false,
                DoNotSendEarnBonusPointEmail = false,
                CardNumber = "VPZS5zXFUex2SJikkXFVrnvt2/R38yomFXwkslgXNKkgAFsjvt94p1h6J/XUEc6yQ5JzmT6+W8AdxuBSbp9e0SXAN60oHuZtWhAgGHhU+GaxJfCQHitc2+VBSZ/DxwW7Bpw="
            };
        MockBootstrapper.Instance.WithRepositoryData(new[] {mockParticipant});
        var input = new EmailOptOutContract
            {
                DoNotSendCuRewardsEmails = true,
                DoNotSendEarnBonusPointEmail = true
            };
        _affinityOptOutApiClient
            .Setup(
                x =>
                x.CallAffinityOptOutStatus(It.IsAny<string>(), 
                                           It.IsAny<string>(),
                                           mockParticipant.DoNotSendEarnBonusPointEmail,
                                           mockParticipant.ParticipantId))
            .Returns<HindaHttpResponse<OptOutResponse>>(x => new HindaHttpResponse<OptOutResponse>
                {
                    StatusCode = AffinityResultCode.Success,
                    ResponseObject = new OptOutResponse { MemberId = "999999999", Status = "success" }
                });
        var response = Controller.Put(mockParticipant.ParticipantId, input);
        var contract = response.ShouldBeSuccess<SuccessContract>();
        var participant = RepositoryFactory.CreateReadOnly<PscuParticipant>().FirstOrDefault(x => x.ParticipantId == mockParticipant.ParticipantId);
        Assert.AreEqual(input.DoNotSendCuRewardsEmails, participant.DoNotSendCuRewardsEmails);
        Assert.AreEqual(input.DoNotSendEarnBonusPointEmail, participant.DoNotSendEarnBonusPointEmail);
    }
    protected override void Configure()
    {
        MockBootstrapper.Override(config => config.For<IEncryptionService>().Use<EncryptionService>());
        _affinityOptOutApiClient = new Mock<IAffinityOptOutApiClient>(MockBehavior.Strict);
        MockBootstrapper.Override(config => config.For<IAffinityOptOutApiClient>().Use(_affinityOptOutApiClient.Object));
    }

这是我的控制器的方法:

    public HttpResponseMessage Put(int participantId, [FromBody]EmailOptOutContract contract)
    {
        if (contract == null)
            return Failure(ApiReturnCodes.InvalidRequestContract
                            , "Invalid Request Contract",
                            string.Format("Contract Is Null in controller method {0}", System.Reflection.MethodBase.GetCurrentMethod()),
                            HttpStatusCode.BadRequest);
        using (new UnitOfWorkScope())
        {
            var participant = GetParticipant(participantId);
            if (participant == null)
            {
                return NotFound(ApiReturnCodes.ParticipantNotFound, "Participant ID not found.");
            }
            participant.DoNotSendCuRewardsEmails = contract.DoNotSendCuRewardsEmails;
            participant.DoNotSendEarnBonusPointEmail = contract.DoNotSendEarnBonusPointEmail;
            string cardNumber = ServiceLocator.Current.GetInstance<IEncryptionService>().Decrypt(participant.CardNumber);
            cardNumber = AesEncrypt(cardNumber);
            string email = null;
            var partic = GetParticipantData(participant.ParticipantId);
            if (partic != null)
                email = partic.Email;
            HindaHttpResponse<OptOutResponse> response =
                _affinityOptOutApiClient.CallAffinityOptOutStatus(cardNumber, email, contract.DoNotSendEarnBonusPointEmail, participant.ParticipantId);
            if (response.StatusCode == AffinityResultCode.Success && response.ResponseObject.Status == "success")
                participant.AffinityMembId = response.ResponseObject.MemberId;
            else
                return BadRequest(ApiReturnCodes.AffinityInternalServerError, response.ExternalErrorMessage);
            return Ok();
        }
    }

在控制器中返回 null 的部分是

HindaHttpResponse<OptOutResponse> response =
                _affinityOptOutApiClient.CallAffinityOptOutStatus(cardNumber, email, contract.DoNotSendEarnBonusPointEmail, participant.ParticipantId);

响应对象为 null,因此在下一个语句中检查它是否成功时,将引发异常。 有谁知道我的设置/退货可能有什么问题导致问题?

谢谢!!!!

使用 Moq 进行单元测试,但对象返回 Null

在您的控制器中,您正在更改参与者。不要发送CuRewards电子邮件到合约对象中的值,这在您的设置中是假的。 您将方法设置为该参数的预期值,因为这是调用安装程序时参与者中包含的值。 Moq 在调用安装程序时按原样获取属性的值,它不会延迟计算对象属性。

设置模拟时,必须使用input

x.CallAffinityOptOutStatus(
    It.IsAny<string>(), 
    It.IsAny<string>(),
    input.DoNotSendEarnBonusPointEmail,
    mockParticipant.ParticipantId)

它需要与您在控制器内进行的特定调用相匹配。