Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

moq setup not returning expected value

i am using Nunit and Autofac's Moq to setup a test

    [TestFixture]
public class SomeTests
{

    [OneTimeSetUp]
    public void Initialize()
    {

    }
    [Test]
    public void SalaryCheck()
    {                              
        using (var mock = AutoMock.GetLoose())
        {
            // Arrange
            mock.Mock<ICommonServices>().Setup(x => x.AddTwoNumbers(1,2)).Returns(5);
            var sut = mock.Create<SomeManager>(); 
            // Act
            int actul = sut.CalculateSalary(1);


            var expected = 5;


            // Assert
            Assert.AreEqual(expected, actul);

        }
    }
}

CalculateSalary function looks like this

  public int CalculateSalary(int hours)
    {
        var addres = _commonService.AddTwoNumbers(5,3);
        if (addres == 5)
        {
            return addres * hours;
        }
        else
        { 
            return  100;
        }
    }

i want AddTwoNumbers function which is a external dependency, to return 5 no matter what. thats why i am setting it up after mocking it. But when i debug this test it looks like it goes inside the calsulate salary function but returns a "0" for AddTwoNumbers function. which is kind of a default or a null value.

it does not return me 5 i.e. what i set it up to return.

like image 644
Raas Masood Avatar asked Jul 21 '16 14:07

Raas Masood


People also ask

What is callback in Moq?

Callbacks. A powerful capability of Moq is to attach custom code to configured methods and properties' getters and setters. This capability is often referred to as Callbacks.

What can be mocked with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces.

How does Moq mock work?

Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.

What does Moq verifiable do?

Verifiable(); 'Setup' mocks a method and 'Returns' specify what the mocked method should return. 'Verifiable' marks this expectation to verified at the end when Verify or VerifyAll is called i.e. whether AddIncomePeriod was called with an object of IncomePeriod and if it returned the same output.


2 Answers

You need to use It.IsAny<int>() i.e.

mock.Mock<ICommonServices>().Setup(x => x.AddTwoNumbers(It.IsAny<int>(),It.IsAny<int>())).Returns(5);
like image 103
gezzahead Avatar answered Sep 30 '22 23:09

gezzahead


When mocking a method that returns an abstraction, make sure that the type in your call to It.IsAny< YourType >() actually matches the type of the param of the method you are mocking.

Given a method that takes an IEnumerable as a param:

interface IQueueItemRepository {
  IQueueItem GetFirstNotIn(IEnumerable<Guid> guids)
}

In the example below, the .Setup will only ever be invoked when .GetFirstNotIn is called with a Collection as param.

Mock<IQueueItemRepository> queueMock = new Mock<IQueueItemRepository>();

queueMock
    .Setup(x => x.GetFirstNotIn(It.IsAny<Collection<Guid>>()))
    .Returns(new QueueItem());

In other words, if the code you are testing never calls .GetFirstNotIn with a Collection, your .Setup will never be invoked. It may be called numerously throughout your code with an IEnumerable as param, but those calls do not match the .Setup.

So be sure to match your param types to your .Setup types:

Mock<IQueueItemRepository> queueMock = new Mock<IQueueItemRepository>();

queueMock
    .Setup(x => x.GetFirstNotIn(It.IsAny<IEnumerable<Guid>>()))
    .Returns(new QueueItem());
like image 28
KVarmark Avatar answered Sep 30 '22 23:09

KVarmark