【问题标题】:Moq Controller to ControllerBase convert errorMoq 控制器到 ControllerBase 转换错误
【发布时间】:2015-03-04 18:54:55
【问题描述】:

当我尝试使用最小起订量以便访问应用程序变量时出现此错误。在这种情况下,应用程序变量是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

【问题讨论】:

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


    【解决方案1】:

    问题是你的AccountServiceController 不是从ControllerBase 继承的,它是从ApiController 继承的。您正在创建的ControllerContext(就错误而言)是针对 MVC 控制器的,并且期望最后一个参数的类型为 ControllerBase

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

    See here for an example of how to mock HttpControllerContext

    【讨论】:

    • 所以我将其更改为 accountController.ControllerContext = new HttpControllerContext(context.Object, new RouteData(), accountController); 但现在我收到错误消息 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
    • 它有不同的签名,所以很遗憾你不能只替换类型。我编辑了我的答案以包含有关如何模拟 HttpControllerContext 的链接。
    • 现在我运行测试时抛出异常。 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
    • 那是一个单独的问题。您的单元测试项目找不到 Newtonsoft.Json 库。检查以确保它们被正确引用,并且您有任何必要的绑定重定向
    • 如果您仍然遇到问题,您应该在 SO 上提出另一个问题。如果我的回答解决了您的问题,您能否将其标记为已接受(即使现在还有另一个问题)?这样,遇到您的特定问题的人就会知道这是一个解决方案。
    【解决方案2】:

    我找到了在 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 1970-01-01
      相关资源
      最近更新 更多