使用 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,因此在下一个语句中检查它是否成功时,将引发异常。 有谁知道我的设置/退货可能有什么问题导致问题?
谢谢!!!!
在您的控制器中,您正在更改参与者。不要发送CuRewards电子邮件到合约对象中的值,这在您的设置中是假的。 您将方法设置为该参数的预期值,因为这是调用安装程序时参与者中包含的值。 Moq 在调用安装程序时按原样获取属性的值,它不会延迟计算对象属性。
设置模拟时,必须使用input
x.CallAffinityOptOutStatus(
It.IsAny<string>(),
It.IsAny<string>(),
input.DoNotSendEarnBonusPointEmail,
mockParticipant.ParticipantId)
它需要与您在控制器内进行的特定调用相匹配。