Moq控制器到ControllerBase转换错误

时间:2015-03-04 18:54:56

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

当我尝试使用moq时,我收到此错误,以便我可以访问应用程序变量。在这种情况下,应用程序变量为ConnectionString,值为TheConnectionString。我需要在GetCompanyList()中提供该值,因为该值在accountService

中使用

错误是:

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

控制器:

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

更新

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

现在,当我的代码到达这一行时(在accountService调用的类中)

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

测试会抛出此错误:System.NullReferenceException: Object reference not set to an instance of an object.1

2 个答案:

答案 0 :(得分:1)

问题是,您的AccountServiceController未从ControllerBase继承,而是从ApiController继承。您正在为MVC控制器创建的ControllerContext(在错误行上),并期望最后一个参数为ControllerBase类型。

您需要使用System.Web.Http中的HttpControllerContext。最后一个参数是IHttpControllerApiController实现。

See here for an example of how to mock HttpControllerContext

答案 1 :(得分:0)

我发现了在Web API期间将ControllerContext对象添加到webcontroller.ControllerContext中的另一种方法,

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