Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to run my test however the I get an "Object reference not set to an instance of an object". Any thoughts? I am using Moq.

Test Method:

     // 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 Method:

     Customer NewCustomer = CustomerRepository.Add();

      //ERROR OCCURS BELOW  
     return Created(Request.RequestUri + "/" + NewCustomer.ID.ToString(), new { customerID = NewCustomer.ID });
share|improve this question
    
When you debug, which object is null? Have you set up your Request object? –  intracept Jun 20 at 3:17
    
The NewCustomer object in the creatcustomer method is populated with the ID and date set in the testmethod –  user3754602 Jun 20 at 3:23
    
And NewCustomer and Request are not null if you run your test in debug mode? When using Moq you need to configure your HttpContext, including your Request object. –  intracept Jun 20 at 3:26
    
NewCustomer is not null, Request is null –  user3754602 Jun 20 at 3:31
add comment

1 Answer

up vote 3 down vote accepted

When you set up Moq, you need to additionally configure your HttpContext, otherwise your Request will be null. You can set it up in a function in your controller that you call at the beginning of your test case, something like:

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

The supporting classes are along the lines of:

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

Lastly, in the top of your Test method, just add this call:

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

That will give you a Request object to work with :)

[edit]

Name spaces you'll need are:

using System.Security.Principal;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
share|improve this answer
    
Thx. Could you state the namespaces required? –  user3754602 Jun 20 at 3:47
    
thx again. one last thing: i get this error "unrecognized escape sequence" on line var fakeIdentity = new GenericIdentity("DOMAIN\username"); –  user3754602 Jun 20 at 3:51
    
I took out my test user name, you should include your own with double backslash escape in the domain\\username. I edited the answer. –  intracept Jun 20 at 3:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.