Terry_Brown
Terry_Brown

Reputation: 1408

Mocking ref parameters

I've cross posted this on the #moq discussion group at: http://groups.google.com/group/moqdisc/browse_thread/thread/569b75fd2cc1829d

hey folks,

I have come across a problem with a mocked ref param that I'm sure must be obvious, but being new to the framework I just can't work it out.

I have the following repository method:

public int SaveCard(int userId, CardPaymentMethodDto
cardPaymentMethodDto)
{
        int? cardId = 0;
        try
        {
                int result = this.dataContext.usp_PaymentMethod_Card_Insert(userId,
                                cardPaymentMethodDto.UserAccountReference,
                                cardPaymentMethodDto.EncryptedCardNumber,
                                cardPaymentMethodDto.BinRange,
                                cardPaymentMethodDto.LastFourDigits,
                                cardPaymentMethodDto.ExpiryMonth,
                                cardPaymentMethodDto.ExpiryYear,
                                cardPaymentMethodDto.IssueNumber,
                                cardPaymentMethodDto.IssuingBank,
                                cardPaymentMethodDto.IssuingCountry,
                                cardPaymentMethodDto.Scheme,
                                cardPaymentMethodDto.StartMonth,
                                cardPaymentMethodDto.StartYear,
                                cardPaymentMethodDto.BillingAddress.House,
                                cardPaymentMethodDto.BillingAddress.SubPremises,
                                cardPaymentMethodDto.BillingAddress.Street,
                                cardPaymentMethodDto.BillingAddress.Town,
                                cardPaymentMethodDto.BillingAddress.County,
                                cardPaymentMethodDto.BillingAddress.Postcode,
                                cardPaymentMethodDto.BillingAddress.Country,
                                cardPaymentMethodDto.DateRegistered,
                                ref cardId);

                if (result <= 0)
                {
                        CompanySystemSqlException tex = new
CompanySystemSqlException("Database communications error");
                        tex.Data.Add("UserId", userId);
                        tex.Data.Add("PaymentMethod", cardPaymentMethodDto.ToString());
                        Logger.LogException("SaveCard: result <= 0", tex);
                        throw tex;
                }
        }
        catch (DbException ex)
        {
                CompanySystemSqlException tex = new
CompanySystemSqlException("Database communications error", ex);
                tex.Data.Add("UserId", userId);
                tex.Data.Add("PaymentMethod", cardPaymentMethodDto.ToString());
                Logger.LogException("SaveCard: DbException", tex);
                throw tex;
        }

        return cardId ?? 0;

}

a the unit test I have is:

[Test]
public void SaveCard_ValidData_ShouldReturnValidCardId()
{
        int cardId;
        int? refCardId = 0;
        dataContext.DefaultValue = DefaultValue.Mock;
        dataContext.Setup( x =>
x.usp_PaymentMethod_Card_Insert(It.IsAny<int>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>(),
                It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(),
                It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
                It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>(), It.IsAny<DateTime>(), ref refCardId)).Returns(1);

        cardId = paymentRepository.SaveCard(1, new CardPaymentMethodDto
{ BillingAddress = new AddressDto { Country = "", County = "", House =
"", Postcode = "", Street = "", SubPremises = "", Town = ""},
                                                                                                        BinRange = "", Cv2 = 123,
                                                                                                        DateRegistered = DateTime.Now, EncryptedCardNumber =
"jumble",
                                                                                                        ExpiryMonth = "02", ExpiryYear = "2030", Id = 1,
IssueNumber = 1, IssuingBank = "", IssuingCountry = "",
                                                                                                        LastFourDigits = "", LastUsed = DateTime.MinValue, Scheme
= "", StartMonth = "", StartYear = "",
                                                                                                        UserAccountReference = ""});

        Assert.That(cardId, Is.EqualTo(1));

}

Now obviously I've had to create the ref param (refCardId) in the unit test, or I can't setup the expected result, but refCardId <> the repository cardId variable, so it's obviously failing (result from the first method is coming back as zero).

I'm sure I'm missing something, but what...?

Thanks for any help, Cheers, Terry

Upvotes: 2

Views: 804

Answers (2)

Starting with Moq 4.8 (which isn't released yet, but there's a pre-release version), you can match ref parameters using It.Ref<T>.IsAny:

dataContext.Setup(x => x.usp_PaymentMethod_Card_Insert(
                           It.IsAny<int>(),
                           It.IsAny<string>(),
                           ...
                           It.IsAny<DateTime>(),
                           ref It.Ref<int?>.IsAny))
           .Returns(1);

Upvotes: 1

mrt181
mrt181

Reputation: 5316

I am not quite sure if i understood the problem but you have assigned 0 to refCardId in your test.

int? refCardId = 0;

Your mock will not change this value because it can't. Your mock is only a proxy that is exactly doing what you are telling it in its Setup method. In this case your Mock will return 1 when it is called. it does not do anything with the refCardId.

Keep in mind that your sut is paymentRepository and its SaveCard method - the mock is only there to test the sut without the dependency on the dataContext.

Upvotes: 0

Related Questions