【问题标题】:Unit testing post controller .NET Web Api单元测试后控制器 .NET Web Api
【发布时间】:2013-03-14 13:31:58
【问题描述】:

我对 .NET Web Api 没有太多经验,但我已经使用它一段时间了,遵循 John Papa 在 Pluralsight 上的 SPA 应用程序教程。该应用程序运行良好,但我现在正在努力解决的问题是对 POST 控制器进行单元测试。

我已经按照这个令人难以置信的指南来了解如何对 Web api 控制器进行单元测试。对我来说唯一的问题是在测试 POST 方法时。

我的控制器如下所示:

    [ActionName("course")]
    public HttpResponseMessage Post(Course course)
    {
        if (course == null)
            throw new HttpResponseException(HttpStatusCode.NotAcceptable);
        try
        {
            Uow.Courses.Add(course);
            Uow.commit();
        }
        catch (Exception)
        {
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }

        var response = Request.CreateResponse(HttpStatusCode.Created, course);

        string uri = Url.Link(routeName: "ControllerActionAndId", 
        routeValues: new { id = course.Id });

        response.Headers.Location = new Uri(uri);

        return response;
    }

我的单元测试看起来像这样:

   [Test]
    public void PostShouldReturnHttpResponse()
    {
        var populatedPostController = new CoursesController(new TestUOW());

        SetupPostControllerForTest(populatedPostController);

        var course = new Course
        {
            Id = 12,
            Author = new UserProfile()
            {
                Firstname = "John",
                Lastname = "Johnson",
            },
            Description = "Testcourse",
            Title = "Test Title"
        };

          var responses = populatedPostController.Post(course);

          ObjectContent content = responses.Content as ObjectContent;
          Course result = (Course)content.Value;
          Assert.AreSame(result, course);
    }

使用帮助功能:

    public static void SetupPostControllerForTest(ApiController controller)
    {

        var config = new HttpConfiguration();
        var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/api/courses/course");
        var route = config.Routes.MapHttpRoute(
            name: "ControllerActionAndId",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: null,
            constraints: new { id = @"^\d+$" }
        );

        var routeData = new HttpRouteData(route, new HttpRouteValueDictionary { { "controller", "courses" }, { "action", "course" } });

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

当我调试单元测试时,它似乎失败了:

        string uri = Url.Link(routeName: "ControllerActionAndId", 
        routeValues: new { id = course.Id });

        response.Headers.Location = new Uri(uri); //Exception because uri = null

似乎 Url.Link 找不到路线。

我也尝试了this 指南,但我真的希望上面的示例能够正常工作。

我在这里错过了一些非常基本的东西吗?

【问题讨论】:

  • 尝试在SetupPostControllerForTest方法controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData;的末尾添加以下行
  • 是的,现在可以使用了!这就是当你累了会发生什么......谢谢!

标签: unit-testing asp.net-web-api nunit


【解决方案1】:

是的,您缺少 Nemesv 提到的配置中的一行。

controller.Request.Properties[HttpPropertyKeys.HttpRouteDataKey] = routeData

如您所见,仅为使用 UrlHelper 配置控制器非常复杂。出于这个原因,我倾向于避免在控制器类中使用 UrlHelper。我通常会引入一个外部依赖项来简化测试,例如 IUrlHelper,它允许我在单元测试中模拟行为。

public interface IUrlHelper
    {
        string Link(string routeName, object routeValues);
        string Route(string routeName, object routeValues);
    }

    public class UrlHelperWrapper : IUrlHelper
    {
        UrlHelper helper;

        public UrlHelperWrapper(UrlHelper helper)
        {
            this.helper = helper;
        }

        public string Link(string routeName, object routeValues)
        {
            return this.helper.Link(routeName, routeValues);
        }

        public string Route(string routeName, object routeValues)
        {
            return this.helper.Route(routeName, routeValues);
        }
    }

我将这个 UrlHelperWraper 注入到真正的 Web API 中,并在测试中模拟 IUrlHelper 接口。通过这样做,您不需要对路由进行所有复杂的配置。

问候, 巴勃罗。

【讨论】:

  • 哇。我怎么能错过那个:/。似乎是处理 UrlHelper 的更干净的方法。不错,谢谢!
  • 嗨@Pablo Cibraro,您能否举一些活生生的例子,我是第一次为web api编写单元测试,并以我在这里登陆的最优化方式创建它们。我不明白您是如何使用 URL 帮助程序的,以及您使用 URl 帮助程序消除的问题中有什么。任何帮助将不胜感激
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多