0

I am getting this error when I am trying to use moq so that I can access application variables. In this case the application variable is ConnectionString with a value of TheConnectionString. I need the value to be available in the GetCompanyList() because the value is used inside accountService class

The Error is :

Error 5 Argument 3: cannot convert from 'Webapp.AccountServiceController' to 'System.Web.Mvc.ControllerBase'

[TestMethod]
public void TestGetCompanyList()
 {
     var accountController = new AccountServiceController();
     var context = new Mock<HttpContextBase>();
     var application = new Mock<HttpApplicationStateBase>();
     var request = new Mock<HttpRequestBase>();

     application.Setup(m => m.Add("ConnectionString","TheConnectionString");
     request.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection { { "X-Requested-With", "XMLHttpRequest" } });
     context.SetupGet(ctx => ctx.Request).Returns(request.Object);
     context.SetupGet(ctx => ctx.Application).Returns(application.Object);

     accountController.ControllerContext = new ControllerContext(context.Object, new RouteData(), accountController); //Error here

     CompanyInput cInput = new CompanyInput();
     cInput.IssuerName = "Be";
     cInput.Ticker = "BR";
     var result = accountController.GetCompanyList(cInput) as IEnumerable<CompanyListResult>;
     Assert.IsNotNull(result);
 }

Controller:

public class AccountServiceController : ApiController
{
    public AccountServiceFacade accoutService;
    public AccountServiceController()
    {
        accoutService = new AccountServiceFacade();
    }

    public AccountServiceController(AccountServiceFacade facade)
    {
        accoutService = facade;
    }

    [System.Web.Http.HttpPost]
    public dynamic GetCompanyList([FromBody]CompanyInput cInput)
    {
        IEnumerable<CompanyListResult> companyList = accoutService.GetCompanyList(cInput);
        return companyList;
    }
}

UPDATE:

 [TestMethod]
    public void TestGetCompanyList()
    {
        var controller = new AccountServiceController();
        var config = new HttpConfiguration();
        var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/test");
        var route = config.Routes.MapHttpRoute("DFS", "api/{controller}/{id}");
        var routeData = new HttpRouteData(route, new HttpRouteValueDictionary
        {
            {
                "ConnectionString", "TheConnectionString" 

            },
            {
                "Username", "TheUserName"
            }
        });
        controller.ControllerContext = new HttpControllerContext(config, routeData, request);
        controller.Request = request;
        controller.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;

        CompanyInput cInput = new CompanyInput();
        cInput.IssuerName = "Be";
        cInput.Ticker = "BR";
        var result = controller.GetCompanyList(cInput) as IEnumerable<CompanyListResult>;
        Assert.IsNotNull(result);

        //Assert.IsNotNull(result.IssueTicker);
    }

Now when my code reaches this line(which is in class that gets called by the accountService)

static string _authUsername = HttpContext.Current.Application["Username"].ToString();

The test throws this error : System.NullReferenceException: Object reference not set to an instance of an object.1

User456789
  • 397
  • 1
  • 3
  • 16

2 Answers2

1

The problem is that your AccountServiceController does not inherit from ControllerBase, it inherits from ApiController. The ControllerContext you're creating (on the line that errors) is for MVC controllers, and expects the last parameter to be of type ControllerBase.

You need to use HttpControllerContext from System.Web.Http. The last parameter is an IHttpController, which ApiController implements.

See here for an example of how to mock HttpControllerContext.

mfanto
  • 14,168
  • 6
  • 51
  • 61
  • So i changed it to, `accountController.ControllerContext = new HttpControllerContext(context.Object, new RouteData(), accountController);` but now i get an error saying `Error 7 The best overloaded method match for 'System.Web.Http.Controllers.HttpControllerContext.HttpControllerContext(System.Web.Http.HttpConfiguration, System.Web.Http.Routing.IHttpRouteData, System.Net.Http.HttpRequestMessage)' has some invalid arguments` – User456789 Mar 04 '15 at 20:35
  • It has a different signature, so you unfortunately can't just replace the type. I edited my answer to include a link on how to mock HttpControllerContext. – mfanto Mar 04 '15 at 20:37
  • Now it is throwing an exception when I ran the test. `TestGetCompanyList threw exception: System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies` – User456789 Mar 04 '15 at 21:15
  • That's a separate issue. Your unit test project can't find the Newtonsoft.Json libraries. Check to make sure they are referenced properly, and that you have any necessary binding redirects – mfanto Mar 04 '15 at 21:24
  • I updated the error I am still getting, I would really appreaciate it if you looked into. – User456789 Mar 04 '15 at 21:36
  • 1
    If you're still having problems, you should ask another question on SO. If my answer fixed your problem, can you mark it as accepted (even though there's now another problem)? That way people that are having your specific issue will know that this is a solution. – mfanto Mar 05 '15 at 22:29
0

I found other way to add a ControllerContext object into your webcontroller.ControllerContext during Web API as follow

[Test]
public void TestMethod()
{
    var controllerContext = new HttpControllerContext();
    var request = new HttpRequestMessage();
    request.Headers.Add("TestHeader", "TestHeader");
    controllerContext.Request = request;
    _controller.ControllerContext = controllerContext;

    var result = _controller.YourAPIMethod();
    //Your assertion
}
Niraj Trivedi
  • 2,370
  • 22
  • 24