Neo
Neo

Reputation: 16239

Moq mock threw an exception of type 'System.ArgumentNullException'

I'm working on unit test cases using moq framework we have used StructureMap and ObjectFactory in our project for dependencies injection.

But When I try to Mock Interface which is not used with Object FActory

I'm getting following exception

'((MyManager)MyManager)' threw an exception of type 'System.ArgumentNullException'

Provided answer works for HomeController.cs methods , but what about those methods which are inside MyManager.TestIdentity(). updated question accordingly.

HomeController.cs

public class HomeController : BaseController
{
    private IMyManager _myManager;
    public IMyManager MyManager
    {
        get
        {
            return _myManager ?? (new MyManager());
        }
        set { _myManager = value; }
    }

    [HttpPost]
    public async Task<IHttpActionResult> TestMock()
    {           
      var response = await MyManager.TestIdentity("demo");
        if (response != null)
        {

            return Ok(identityResponse);
        }

        throw new ApiException(HttpStatusCode.NotFound, 10001,
            "failed");
    }
}

MyManager.cs

public class MyManager : IMyManager
{
    private IMyRespository _myRepository;

    public IMyRespository MyRespository
    {
        get
        {
            return _myRepository;
        }
        set { _myRepository = value; }
    }

    public async Task<CustomerResponseObject> TestIdentity(string demo)
    {
        var result = await MyRespository.GetRoles("user");
    }
}

Now inside Unit Test project I want to mock method MyRespository.GetRoles

[TestMethod]
public async Task CreateIdentityWithNullMag()
{
    try
    {            

  //I tried same mock with MyRespository.GetRoles
    var mockIMyRespository = new Mock<IMyRespository>();
            mockIMyRespository .Setup(p =>p.GetRoles(It.IsAny<string>())).
        ReturnsAsync(new RoleObject()
        {
            Name = "admin"
        });
    ObjectFactory.Inject(mockIMyRespository .Object);    


    var controller = new HomeController();
    //working for TestIdentity , failed for GetRoles , i mean GetRole method does not get Mock it has Null exception :(
    controller.MyManager = mockIMyManager.Object;

    await controller.TestMock(request); 

}

'MyRespository' threw an exception of type 'System.ArgumentNullException'

What should be done? to success this Mock?

Upvotes: 0

Views: 2179

Answers (2)

Bernhard Hiller
Bernhard Hiller

Reputation: 2407

Since HomeController.MyManager has a public setter, I'd use that:

var controller = new HomeController();
mockIMyManager.SetupGet(x=>x.MyRepository).Returns(mockIM‌​yRespository.Object)‌​;
controller.MyManager = mockIMyManager.Object;
await controller.TestMock(request); 

Upvotes: 2

Nkosi
Nkosi

Reputation: 247571

Assuming the following based on your example

public interface IMyManager {
    Task<CustomerResponseObject> TestIdentity(string username);
}

public interface IMyRespository {
    Task<RoleObject> GetRole(string username);
}

public class RoleObject {
    public string Name { get; set; }
}

public class CustomerResponseObject {
    public RoleObject Role { get; set; }
}

Where MyManager is the system under test

public class MyManager : IMyManager {
    private IMyRespository myRepository;

    public MyManager(IMyRespository myRepository) {
        this.myRepository = myRepository;
    }

    public async Task<CustomerResponseObject> TestIdentity(string username) {
        var role = await myRepository.GetRole(username);

        var result = new CustomerResponseObject {
            Role = role
        };
        return result;
    }
}

Here is a unit test to test TestIdentity

[TestClass]
public class MiscUnitTest {
    [TestMethod]
    public async Task MyManager_TestIdentity_With_User_Should_Return_AdminRole() {
        //Arrange
        string username = "user";
        string expectedRole = "admin";
        var mockIMyRespository = new Mock<IMyRespository>();
        mockIMyRespository.Setup(p => p.GetRole(It.IsAny<string>())).
        ReturnsAsync(new RoleObject() {
            Name = expectedRole
        });

        var sut = new MyManager(mockIMyRespository.Object);

        //Act
        var result = await sut.TestIdentity(username);

        //Assert
        Assert.IsNotNull(result);
        Assert.IsNotNull(result.Role);
        Assert.AreEqual(expectedRole, result.Role.Name);
    }
}

Upvotes: 1

Related Questions