Testing a method in MVC which makes calls to Repositories

59 views Asked by At

I have a MVC method like so:

public ActionResult ChangeStatus(string productId, string statusToChange)
{
    var productToChangeStatus = _updateProductRepository.GetUpdateProduct(productId);

    if (statusToChange.ToLower() == ChangeStatusTo.Disable)
    {
        productToChangeStatus.Active = "false";
    }
    else
    {
        productToChangeStatus.Active = "true";
    }

    _updateProductsManager.UpsertProduct(productToChangeStatus);

    return Json(new { success = true });
}

This method gets an existing product based on the 'productId', changes the 'Active' property on it based on the 'statusToChange' value, saves it back and returns a Json with success.

The test setup is like so:

private ProductController _controller;
private Mock<IUpdateProductRepository> _iProductRepository;


[TestInitialize]
public void TestSetup()
{
    _iProductRepository = new Mock<IUpdateProductRepository>();
    _controller = new ProductController(_iProductRepository.Object);
}

Wrote a test method like so:

[TestMethod]
public void Disable_A_Product_Which_Is_Currently_Enabled()
{
    const string productId = "123";

    var productBeforeStatusChange = new Product()
    {
        Active = "true",
        Id = new Guid().ToString(),
        Name = "TestProduct",
        ProductId = "123"
    };

    var productAfterStatusChange = new Product()
    {
        Active = "false",
        Id = new Guid().ToString(),
        Name = "TestProduct",
        ProductId = "123"
    };

    _iProductRepository.Setup(r => r.GetUpdateProduct(productId)).Returns(productBeforeStatusChange);

    _iProductRepository.Setup(r => r.UpsertProduct(productBeforeStatusChange)).Returns(productAfterStatusChange);

    var res = _controller.ChangeStatus("123", "disable") as JsonResult;
    Assert.AreEqual("{ success = true }", res.Data.ToString());
}

The test fails with this error:

Object reference not set to an instant of the object.

On debugging I found that it fails inside the

if(...)

condition where the actual setting of the Active property is happening. Since the productId that's being passed is not real a product object can't be retrieved for the code to work on.

I tried to use Mock but I think my usage is not correct.

So what I want to know is, how to test a method like this where a method that returns an ActionResult is in turn calling the repository to work with object(s).

Thanks in advance.

1

There are 1 answers

2
SBirthare On BEST ANSWER

You seems to be missing setup for

_updateProductsManager.UpsertProduct()

The way you setup GetUpdateProduct() method you ought to setup UpsertProduct() on the mock instance.