【问题标题】:Weird "Object reference not set to an instance of an object" error while using Moq使用 Moq 时出现奇怪的“对象引用未设置为对象的实例”错误
【发布时间】:2014-06-20 03:11:26
【问题描述】:

我正在尝试运行我的测试,但是我得到一个“对象引用未设置为对象的实例”。有什么想法吗?我正在使用起订量。

测试方法:

     // Arrange
    Mock<ICustomerRepository> CustomerRepo = new Mock<ICustomerRepository>();
    Customer NewCustomer = new Customert() { ID = 123456789, Date = DateTime.Now };
    CustomerRepo.Setup(x => x.Add()).Returns(NewCustomer);
    var Controller = new CustomerController(CustomerRepo.Object, new Mock<IProductRepository>().Object);

    // Act
    IHttpActionResult actionResult = Controller.CreateCustomer();

CreateCustomer 方法:

     Customer NewCustomer = CustomerRepository.Add();

      //ERROR OCCURS BELOW  
     return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new { customerID = NewCustomer.ID });

【问题讨论】:

  • 调试时,哪个对象为空?您是否设置了 Request 对象?
  • creatcustomer 方法中的 NewCustomer 对象填充了 testmethod 中设置的 ID 和日期
  • 如果您在调试模式下运行测试,NewCustomer 和 Request 不为空?使用 Moq 时,您需要配置 HttpContext,包括您的 Request 对象。
  • NewCustomer 不为空,请求为空

标签: c# unit-testing moq asp.net-web-api2


【解决方案1】:

设置起订量时,需要额外配置你的HttpContext,否则你的Request会为null。您可以在测试用例开始时调用的控制器中的函数中设置它,例如:

private Mock<ControllerContext> GetContextBase()
{
    var fakeHttpContext = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    var response = new Mock<HttpResponseBase>();
    var session = new MockHttpSession();
    var server = new MockServer();
    var parms = new RequestParams();
    var uri = new Uri("http://TestURL/Home/Index");

    var fakeIdentity = new GenericIdentity("DOMAIN\\username");
    var principal = new GenericPrincipal(fakeIdentity, null);

    request.Setup(t => t.Params).Returns(parms);
    request.Setup(t => t.Url).Returns(uri);
    fakeHttpContext.Setup(t => t.User).Returns(principal);
    fakeHttpContext.Setup(ctx => ctx.Request).Returns(request.Object);
    fakeHttpContext.Setup(ctx => ctx.Response).Returns(response.Object);
    fakeHttpContext.Setup(ctx => ctx.Session).Returns(session);
    fakeHttpContext.Setup(ctx => ctx.Server).Returns(server);

    var controllerContext = new Mock<ControllerContext>();
    controllerContext.Setup(t => t.HttpContext).Returns(fakeHttpContext.Object);

    return controllerContext;
}

支持类如下:

/// <summary>
/// A Class to allow simulation of SessionObject
/// </summary>
public class MockHttpSession : HttpSessionStateBase
{
    Dictionary<string, object> m_SessionStorage = new Dictionary<string, object>();

    public override object this[string name]
    {
        get {
            try
            {
                return m_SessionStorage[name];
            }
            catch (Exception e)
            {
                return null;
            }
        }
        set { m_SessionStorage[name] = value; }
    }

}

public class RequestParams : System.Collections.Specialized.NameValueCollection
{
    Dictionary<string, string> m_SessionStorage = new Dictionary<string, string>();

    public override void Add(string name, string value)
    {
        m_SessionStorage.Add(name, value);
    }

    public override string Get(string name)
    {
        return m_SessionStorage[name];
    }

}

public class MockServer : HttpServerUtilityBase
{
    public override string MapPath(string path)
    {

        return @"C:\YourCodePathTowherever\" + path;
    }
}

最后,在您的 Test 方法的顶部,只需添加以下调用:

// Arrange
HomeController controller = new HomeController();
controller.ControllerContext = GetContextBase().Object;

这会给你一个 Request 对象来使用:)

[编辑]

您需要的命名空间是:

using System.Security.Principal;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

【讨论】:

  • 谢谢。您能否说明所需的命名空间?
  • 再次感谢。最后一件事:我在 var fakeIdentity = new GenericIdentity("DOMAIN\username");
  • 我取出了我的测试用户名,你应该在域\\用户名中包含你自己的双反斜杠转义。我编辑了答案。
【解决方案2】:

在 mock 的声明中将类型设置为 Mock 给我带来了问题。

Mock<ICustomerRepository> CustomerRepo = new Mock<ICustomerRepository>();

按照以下方式删除后可能会避免此问题

var CustomerRepo = new Mock<ICustomerRepository>();

【讨论】:

    猜你喜欢
    • 2013-02-10
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2012-08-31
    • 2011-11-21
    • 2012-10-01
    相关资源
    最近更新 更多