Moq mock 抛出了类型 'System.ArgumentNullException' 的异常

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

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

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

我遇到以下异常

'((MyManager)MyManager)' threw an exception of type '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); 

}

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

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

因为 HomeController.MyManager 有一个 public setter,我会使用它:

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

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

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