Moq setup causing null

I'm new to Unit Testing, and Moq, so if I'm completely wrong in my method or understanding, please assist me.

I have a logic method I am testing. I've commented out the logic, but all it does is check a few values in the 'model' and returns if there's a problem. In the case we're looking at, there's no problem.

        public ReplyDto SaveSettings(SnowballDto model)
        {

            // Some logic here that reads from the model.

            var result = _data.SaveSettings(model);
            return result;
        }

My test, using NUnit and MOQ, looks like this:

_logic = new SnowballLogic(mockSnowballData.Object, mockLog.Object);

           mockSnowballData
                .Setup(x => x.SaveSettings(SnowballDto_Good))
                .Returns(new ReplyDto {
                    IsSuccess = true,
                    Message = "Saved",
                    ReplyKeyID = 1
                });

In each test, I call a private setup function that sets up the things I'll be using.

 private void SetupData()
        {
            SnowballDto_Good = new SnowballDto {
                FirstPaymentDate = DateTime.UtcNow,
                ID = 1,
                OrderedIDPriority = new List<int>(),
                SnowballTypeID = 1,
                TargetPayment = 1000
            };

            DebtDtoList_ThreeDebt.Clear();
            DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 1, Description = "Debt 1", ManualSnowballPriority = 1, MinimumMonthlyPaymentAmount = 140, OpeningBalance = 5000, RunningData = new DebtRunningDto { Balance = 5000 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 10 });
            DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 2, Description = "Debt 2", ManualSnowballPriority = 2, MinimumMonthlyPaymentAmount = 90, OpeningBalance = 1600, RunningData = new DebtRunningDto { Balance = 1600 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 15 });
            DebtDtoList_ThreeDebt.Add(new DebtDto { ID = 3, Description = "Debt 3", ManualSnowballPriority = 3, MinimumMonthlyPaymentAmount = 300, OpeningBalance = 9000, RunningData = new DebtRunningDto { Balance = 9000 }, OpeningDate = DateTime.UtcNow, SnowballID = 1, StandardRate = 20 });


        }

So, my understanding of MOQ is that I am saying "When the SnowballData class's "SaveSettings" methid is called, and a "SnowballDto_Good" object is passed in, always return a new ReplyDto with IsSuccess = true.

Therefore, when I make the call:

var result = _data.SaveSettings(model);

It should return ReplyDto with IsSuccess = true

However, when I put a breakpoint in when I call 'SaveSettings', it returns null all the time.

If I change my setup to:

.Setup(x => x.SaveSettings(It.IsAny<SnowballDto>()))

The test passes. Why is it returning null when I give it a real SnowballDto?


well, it seems you are passing an instance of SnowballDto named model in the "act" part of your test

var result = _data.SaveSettings(model);

In the setup of moq, however, you configure it to return a new ReplyDto only when the instance SnowballDto_Good is specified to SaveSettings . In all other cases, the method's mock is not configured, and - in case of a loose mocking strategy (the default) - it will return the default value for SaveSettings return type. In this case: null.

When you're using It.IsAny<SnowballDto> you are basically telling moq to configure SaveSettings to return a new instance not only then the instance SnowballDto_Good is passed to it, but any instance of that type.

What you need to do is to change your "act" part of your test as follows:

var result = _data.SaveSettings(SnowballDto_Good);

then it will work with your original mock setup, because the correct instance will be passed to SaveSettings .

This is precisely why I like to instantiate my mocks using MockBehavior.Strict.

Instead of returning null, it will throw an exception that will tell you that you didn't configure your mock correctly.

Hope this helps.

链接地址: http://www.djcxy.com/p/35348.html

上一篇: 与Moq的Xunit和Mock数据

下一篇: Moq设置导致null