0

I am new to nSubstitute. And I am writing test method for my controller class. I have a TestMethod called GetDefaultStateTest() which having Substitute class as shown below

[TestMethod]
    public void GetDefaultStateTest()
    {
        var _GetDefaultState = Substitute.For<CustomerController>(ICustomer cus);
        Assert.IsNotNull(_GetDefaultState.GetDefaultState());
    }

Because my controller class having parameterized constructor as below.

public class CustomerController : Controller
{
private readonly ICustomer _customer;
  public CustomerController(ICustomer customer)
  {
    _customer = customer;
  }

  public string GetDefaultState()
  {
        // Get default state from settings table
        List<tblSettings> settings = new List<tblSettings>();
     // Calling service method GetSettings
        settings = _customer.GetSettings();
        var defaultState = from setting in settings
                           where setting.Desc == "DefaultState"
                           select setting.Settings;
        string strState = "";
        foreach (var oState in defaultState)
        {
            strState = oState;
            break;
        } 
        return strState;
   }
}

While run the test method, it raise null reference issue. Because of parameter ICustomer is null

var _GetDefaultState = Substitute.For<CustomerController>(ICustomer cus);

How to resolve this problem.

tereško
  • 58,060
  • 25
  • 98
  • 150
user792223
  • 61
  • 3
  • 8

1 Answers1

1

If you are testing your controller class then you do not want to substitute for it, you want to use a real one (otherwise you'd just be testing a fake object "works" :)). Where you may want to substitute is for that class's dependencies, in this case, ICustomer.

[TestMethod]
public void GetDefaultStateTest()
{
    var customer = Substitute.For<ICustomer>();
    var controller = new CustomerController(customer);
    Assert.IsNotNull(controller.GetDefaultState());
}

You may then want to fake out the ICustomer.GetSettings() method so you can test what your controller does with that data:

[TestMethod]
public void GetDefaultStateTestFromSettings()
{
    var customer = Substitute.For<ICustomer>();
    customer.GetSettings().Returns(somethingSensible);
    var controller = new CustomerController(customer);
    Assert.AreEqual(expectedDefaultState, controller.GetDefaultState());
}

As an aside, sometimes it makes more sense to use real objects (say, a real implementation of ICustomer) rather than substitutes. This will depend on how well-defined the interactions with the dependencies are, where you want to define the boundaries of your system under test, and how much confidence the test gives you that the system under test is working correctly. Or put more simply, whatever makes it easy and reliable to test. :)

Hope this helps.

David Tchepak
  • 9,826
  • 2
  • 56
  • 68