Reputation: 16239
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
Reputation: 2407
Since HomeController.MyManager
has a public setter, I'd use that:
var controller = new HomeController();
mockIMyManager.SetupGet(x=>x.MyRepository).Returns(mockIMyRespository.Object);
controller.MyManager = mockIMyManager.Object;
await controller.TestMock(request);
Upvotes: 2
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