Moq mock抛出了类型' System.ArgumentNullException'

时间:2016-08-17 08:52:28

标签: c# unit-testing mocking moq

我正在使用moq framework处理单元测试用例 我们在项目中使用了StructureMapObjectFactory来进行依赖注入。

但是当我尝试使用不与Object FActory一起使用的模拟接口

我得到了异常

  

'((MyManager)MyManager)'抛出一个例外   键入' System.ArgumentNullException'

提供的答案适用于HomeController.cs方法,但那些MyManager.TestIdentity()内的方法呢? 相应地更新了问题。

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");
    }
}

现在在单元测试项目中 我想模拟方法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); 

}
  

&#39; MyRespository&#39;抛出一个例外   键入&#39; System.ArgumentNullException&#39;

该怎么办?成功这个模拟?

2 个答案:

答案 0 :(得分:2)

由于HomeController.MyManager有公共制定者,我会使用:

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

答案 1 :(得分:1)

根据您的示例假设以下内容

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; }
}

MyManager是被测系统

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;
    }
}

以下是测试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);
    }
}