zoukankan      html  css  js  c++  java
  • ASP.NET Web API

    ASP.NET Web API integration testing with in-memory hosting

     http://www.strathweb.com/2012/06/asp-net-web-api-integration-testing-with-in-memory-hosting/

    http://zamd.net/2012/05/04/claim-based-security-for-asp-net-web-apis-using-dotnetopenauth/

    In-memory hosting is one of the hidden gems of ASP.NET Web API. While the community, forums, bloggers have been buzzing about web-host and self-host capabilities of Web API, aside from theterrific post by Pedro Felix, very little has been said about in memory hosting.

    Let me show you an example today, how a lightweight Web API server can be temporarily established in memory (without elevated priviliges, or cannibalizing ports like self host) and used to perform integration testing, allowing you to test almost the entire pipeline, from the request to the response.

    Intro to in memory hosting

    In memory hosting comes down to creating an instance of HttpServer class. HttpServer itself is derived from HttpMessageHandler, and can be treated like one. It allows you to perform direct communication between the server runtime, and the client side, through the use of HttpClient orHttpMessageInvoker. As soon as the purpose for the existance of the server is fulfilled, you can very easily dispose of it.

    As mentioned, the main advantage of this over self-host, is that it doesn’t require a port or a base address; since by design it doesn’t run on localhost, but truly in memory. You can pretty much mock the entire server environment/runtime in memory!

    All this makes in-memory hosting incredibly useful and powerful tool for various testing scenarios, especially for integration testing. It allows you to quickly test the entire processing pipeline of your server, including controllers, filters/attributes, message handlers and formatters. From the moment the HTTP request leaves the client, all the way to the point when the response is received.

    We will use integration testing as an example of application of in-memory hosting. A disclaimer here: it will by no means be fullly-fledged, production-ready testing sample or methodology walkthrough; rather my focus here is to show how you can leverage on Web API in-memory hosting to facilitate integration testing scenarios.

    My test application

    In my test application, I would like to test the following things:
    – submitting a request
    – a message handler
    – custom action filter attribute
    – controller action
    – JSON formatter applied to the incoming response
    – receiving the response

    I will scrape the application together from the various pieces of code I have been blogging about over the weeks. The repository will come from this post, the filter will be a simplified version of the caching filter from here, and the handler will be the api key handler from here.

    The handler will check for an “apikey”, if the request doesn’t have it, then error will be returned.

    The filter’s role will be to add cache control directives to the response. That is what I will be checking for in the tests.

    Setting up test project

    My favorite testing framework is xUnit, but obviously any one would do here. Let’s add the test project then, download xUnit and get going.

    I will set up the server in the test class’ constructor.

    The configuration of the in-memory Web API host is almost exactly the same as configuring web- or self- host. You need specify, at the very least, the routes to be used, and that is done through the familiar HttpConfiguration. Server is instantiated by passing the configuration to the HttpServerconstructor.

    Notice how I wire up the Message Handler which I will be wanting to test in the server’s configuration. The server’s instance itself will be a private property of the class and will be reused between different test methods.

    Since our test class will implementIDisposable, we need to cater for the Dispose method:

    Now, what I will be testing against is:
    – get all items from the repository via GET
    – get single item from the repository via POST
    – remove single item from the repository via POST
    – get all items from the repository via GET without API key (fail on purpose)

    In each case we will be starting off by constructing the HttpRequestMessage, sending it to our in memory server, and receiving its response in the form of HttpResponseMessage, which will be used for all kinds of Asserts. What’s important to re-iterate here, this is all simulating the normal end-to-end behavior of the Web API – so in other words a great integration test.

    I will be using HttpClient‘s SendAsync method for sending data to the server, since it acceptsHttpRequestMessage, rather than POCO objects, so would allow us to simulate the behavior of the browser.

    Before proceeding, I will add up two private helpers, which will be used for constructingHttpRequestMessages to be sent to the server – one for generic HttpRequestMessage and one with an ObjectContent.

    Get all items

    So we create the HttpClient and pass our server to it, as if we were passing the DelegatingHandler – how cool is that? I have an expected JSON response, in the string form, which I will use to compare with the actual result. Then we have a bunch of other asserts:
    – response not null
    – response content type is “application/json”
    – object extracted from the response, IQueryable of Url, contains 3 items (to check if the apikey handler didn’t stop the request)
    – two CacheControl asserts (to check if our ActionFilter works)
    – comparison to the the expected Json (to check if JSON formatter works)

    So, in a few lines of simple code, we have tested so much of the actual, real world functionalities.

    Get single item

    This is very similar to the one before, except this time we will be submitting an object. I instantiateUrl object, and send it to the controller. I can serialize the object using JSON.NET and compare the output (the controller returns the added object) – both by reading the content as string and comparing to JSO.NET serialized variable, and by reading the underlying type from the response.

    Remove single object

    In this test, I will be removing an item from the repository. This is done by posting an item ID as integer. The controller returns the deleted object instance. Again, I can compare the JSON output to the expected one, as well as extract the underlying POCO object and compare that (in this case I’m just comparing its ID).

    Request without apikey

    This last test is an expected failure, as we make a request without providing the apikey. We can verify that the handler works just fine, and that the returned response is a denial of access (403 code).

    Running the test

    We can now compile the test project, and run the tests in xUnit. Since I am allergic to consoles, let’s use the GUI.

    As you can see all the tests pass like a charm. This helps us to verify that it’s not just our unit logic that’s correct, but the entire pipeline behaves like it should. In a few simple methods, we have managed to test so much, by working only with HTTP request and HTTP response; all thanks to in memory hosting.

    Summary and source code

    As mentioned before, to me in memory hosting is one of the hidden gems of ASP.NET Web API. You should really take advantage of this awesome funcionality. It takes unit/integration testing to new heights, allowing you to produce even more robust applications.

    Till next time!

  • 相关阅读:
    DPDK 多进程
    dpdk helloword
    dpdk-ring-ping
    【基于python实现UI自动化】3.0 selenium
    算法题:实现 strStr()函数
    python程序设计:某体操比赛共有10名运动员参加,12名评委将根据运动员表现进行评分(满分10分),请编写Python程序,解决下列问题:
    Scrapy框架实战(五):通用爬虫 CrawlSpider
    python爬虫爬取_高德地图_主要城市迁徙意愿排行榜_19年至今数据
    年轻就该多尝试,教你20小时Get一项新技能
    LeetCode:283.移动零——简单
  • 原文地址:https://www.cnblogs.com/fx2008/p/3209932.html
Copyright © 2011-2022 走看看