当使用带有ref参数的mocked方法时,断言MustHaveHappened失败

时间:2015-08-18 14:53:50

标签: unit-testing assert fakeiteasy

我使用FakeItEasy来模拟单元测试的方法。其中一种方法(使用REF参数 - 可能这很重要)将数据保存在数据库中,因此它被模拟为“什么都不做”

A.CallTo(() => mockedUserRepository.Save(ref mwbeUserData)).MustHaveHappened(Repeated.Exactly.Once);

。但在这种情况下,最后一个断言失败

Assertion failed for the following call:
    MobileWallet.Common.DAL.IMwbeUserRepository.Save(<NULL>)
  Expected to find it exactly once but found it #0 times among the calls:
    1: MobileWallet.Common.DAL.IMwbeUserRepository.Get(userName: \"AAA\")
    2: MobileWallet.Common.DAL.IMwbeUserRepository.Save(user: MobileWallet.Common.Repository.MwbeUserData)

有错误:

[TestMethod]
public void AddUser_MwbeUserObjectReturned()
{
    //Arrange

    MwbeUserRegistrationIn userRegistrationIn = new MwbeUserRegistrationIn()
    {
        BirthDate = DateTime.Today,
        Email = "www@wp.pl",
        FirstName = "Adam",
        SecondName = "Ada2",
        UserName = "AAA"
    };

    //mock mockedNotificationService and related: 
    INotificationService mockedNotificationService = A.Fake<INotificationService>();
    //TODO: create notofication service

    //mock IMwbeUserRepository and related
    IMwbeUserRepository mockedUserRepository = A.Fake<IMwbeUserRepository>();

    MwbeReturnData<MwbeUserData> mwbeReturnData = new MwbeReturnData<MwbeUserData>(MwbeResponseCodes.NotFound);          

    MwbeUserData mwbeUserData = mwbeReturnData.Data;

    A.CallTo(() => mockedUserRepository.Get(userRegistrationIn.UserName)).Returns(mwbeReturnData);
    A.CallTo(() => mockedUserRepository.Save(ref mwbeUserData)).DoesNothing();

    MwbeUserService userService = new MwbeUserService(mockedUserRepository, mockedNotificationService);

    //Act
    MwbeUser user = userService.AddUser(userRegistrationIn);

    //Assert
    Assert.IsNotNull(user);            
    Assert.AreEqual(userRegistrationIn.Email, user.Email);
    Assert.AreEqual(userRegistrationIn.UserName, user.UserName);
    Assert.AreEqual(userRegistrationIn.FirstName,user.FirstName);
    Assert.AreEqual(userRegistrationIn.SecondName, user.SecondName);
    Assert.AreEqual(userRegistrationIn.BirthDate, user.BirthDate);

    A.CallTo(() => mockedUserRepository.Get(userRegistrationIn.UserName)).MustHaveHappened(Repeated.Exactly.Once);
    A.CallTo(() => mockedUserRepository.Save(ref mwbeUserData)).MustHaveHappened(Repeated.Exactly.Once);
}

完整的测试代码

MwbeUserData mwbeUserData = mwbeReturnData.Data;

更新1:

请注意,对于此方法Save的两次调用,mwbeUserData的值都是相同的

class bottom(middle_0, middle_1):
    pass

如果这是null(但事实并非如此)。

可能REF参数的语法有问题吗?我读到应该使用名为 AssignsOutAndRefParameters 的方法,但我不确切知道如何使用它。

现在我将使用MATCHES参数使其更通用。

1 个答案:

答案 0 :(得分:3)

  

我认为这是因为您对mwbeUserData实例进行断言

@Old Fox有权利。

如果使用mockedUserRepository.Save(ref mwbeUserData)输入调用null,则询问FakeItEasy(mwbeUserData在您进行检查时必须为空)。它没有看到这样的内容,因为传递给MwbeUserData内的mockedUserRepository.Save的{​​{1}}似乎不是空的。

如果你认为测试应该通过,也许放宽你的约束会有所帮助,就像FakeItEasy: mocked method is not returning expected result一样。

另请注意,参数的AddUser ness对此行为没有影响。对于“普通”参数,会发生相同的约束匹配。默认情况下,只有ref个参数可以免除。有关详细信息,请参阅FakeItEasy文档中的Argument Constraints,以及有关如何使用自定义参数匹配器的更多信息。