I have a customer class which accepts an IDbGateway interface as a constructor parameter. I need to write a unit test CalculateWage_HourlyPayed_ReturnsCorrectWage for the class using NUnit and NSubstitute. My unit test works fine when I pass anyId. But I want to pass Arg.Any<int>() instead of anyId. At the moment my test fails because decimal actual = sut.CalculateWage(Arg.Any<int>()); gives NullReferenceException. Why is my code working for anyId value pass but not for Arg.Any<int>()?
Here are the target members
public class Customer
{
private readonly IDbGateway _gateway;
public Customer(IDbGateway gateway)
{
_gateway = gateway;
}
public decimal CalculateWage(int id)
{
WorkingStatistics ws = _gateway.GetWorkingStatistics(id);
decimal wage;
if (ws.PayHourly)
{
wage = ws.WorkingHours * ws.HourSalary;
}
else
{
wage = ws.MonthSalary;
}
return wage;
}
}
public interface IDbGateway
{
WorkingStatistics GetWorkingStatistics(int id);
}
public class DbGateway : IDbGateway
{
public WorkingStatistics GetWorkingStatistics(int id)
{
throw new NotImplementedException();
}
}
public class WorkingStatistics
{
public decimal HourSalary { get; set; }
public int WorkingHours { get; set; }
public decimal MonthSalary { get; set; }
public bool PayHourly { get; set; }
}
Here is the test in question
[TestFixture]
public class CustomerTestsWithNSubstitute
{
[Test]
public void CalculateWage_HourlyPayed_ReturnsCorrectWage()
{
var gateway = Substitute.For<IDbGateway>();
var workingStatistics = new Business.Demo.WorkingStatistics()
{ PayHourly = true, HourSalary = 100, WorkingHours = 10 };
const int anyId = 1;
//gateway.GetWorkingStatistics(anyId).ReturnsForAnyArgs(workingStatistics);
gateway.GetWorkingStatistics(Arg.Any<int>()).ReturnsForAnyArgs(workingStatistics);
const decimal expectedWage = 100 * 10;
var sut = new Customer(gateway);
//decimal actual = sut.CalculateWage(anyId);
decimal actual = sut.CalculateWage(Arg.Any<int>());
Assert.That(actual, Is.EqualTo(expectedWage).Within(0.1));
}
}