<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Richard Hatherall</title>
    <description>The latest articles on DEV Community by Richard Hatherall (@rhatherall).</description>
    <link>https://dev.to/rhatherall</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F261152%2F0214a27c-d00f-4f19-8ae7-669ca4f4954b.jpeg</url>
      <title>DEV Community: Richard Hatherall</title>
      <link>https://dev.to/rhatherall</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rhatherall"/>
    <language>en</language>
    <item>
      <title>Matching HTTP requests with WebMocks in Delphi</title>
      <dc:creator>Richard Hatherall</dc:creator>
      <pubDate>Wed, 17 Mar 2021 11:26:22 +0000</pubDate>
      <link>https://dev.to/rhatherall/matching-http-requests-with-webmocks-in-delphi-33ac</link>
      <guid>https://dev.to/rhatherall/matching-http-requests-with-webmocks-in-delphi-33ac</guid>
      <description>&lt;p&gt;If you've been following along, you'll now know how to set up a DUnitX project with WebMocks and understand how to define the HTTP response for a stubbed request. You've also seen the most basic form of request matching in the previous articles, e.g. &lt;code&gt;StubRequest('GET', '/')&lt;/code&gt;. The &lt;code&gt;StubRequest&lt;/code&gt; method starts with the required elements of a request match, the HTTP method &lt;code&gt;GET&lt;/code&gt; in this example, along with the document path &lt;code&gt;/&lt;/code&gt;. Let's take a closer look at how we can match requests with WebMocks in Delphi.&lt;/p&gt;

&lt;h1&gt;
  
  
  Methods and Document Paths
&lt;/h1&gt;

&lt;p&gt;The HTTP method is one of the most significant components of the request. Therefore, the &lt;code&gt;StubRequest&lt;/code&gt; method puts that upfront, along with the intended document path. They are both specified as &lt;code&gt;string&lt;/code&gt; arguments, allowing arbitrary method and path values. RESTful endpoints can be matched as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create Widget
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// List all Widgets
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Show Widget 1
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Update Widget 1
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'PATCH'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'PUT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Delete Widget 1
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'DELETE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from these examples, there are often many similar requests that you will need to distinguish correctly based upon method and path alone.&lt;/p&gt;

&lt;p&gt;Sometimes it is useful to catch more than a single value, and you might, for example, want to stub the update requests represented by &lt;code&gt;PATCH&lt;/code&gt; and &lt;code&gt;PUT&lt;/code&gt; with a single call. A simple wildcard "*" string matches any value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the eagle-eyed amongst you will be saying, "won't that match the GET and DELETE actions too?". Yes, it will. Most test scenarios don't need all of the actions defined simultaneously. If you need to, then it is easily achieved through the order of stub definitions. All request stubs are evaluated in the order they are defined, and the first matching stub is applied.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'DELETE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/widgets/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// PATCH and PUT
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another potential problem here is the ID in the URL. You might not know the exact number when writing the test, or you might want to match and respond the same to multiple identical requests for different resources. Unfortunately, the &lt;code&gt;*&lt;/code&gt; is a simple wildcard only, and you can't combine it with a partial path. Luckily, WebMocks does allow regular-expressions in place of the path argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get Widget with an integer ID
&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TRegEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/widgets/\d+'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be sure to include &lt;code&gt;System.RegularExpressions&lt;/code&gt; in your &lt;code&gt;uses&lt;/code&gt; clause.&lt;/p&gt;

&lt;h1&gt;
  
  
  Matching Query Parameters
&lt;/h1&gt;

&lt;p&gt;The document path is only one part of the URI. It is just as essential to be able to match by query parameters. Query parameters can be matched by name and value easily. For example, to match a specific value for a parameter supplied on the URL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithQueryParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Action'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'DoSomething'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all you want is to test for the presence of a particular query parameter, you can use a simple wildcard &lt;code&gt;*&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithQueryParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Action'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using regular expressions is also supported for matching values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithQueryParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Action'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TRegEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'List.*'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Matching Headers
&lt;/h1&gt;

&lt;p&gt;Headers provide a lot of information about a request, and you are likely going to want to match a request by header values.&lt;br&gt;
Let's start with a basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'content-type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'video/mp4'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example will match any request with a &lt;code&gt;content-type&lt;/code&gt; header of &lt;code&gt;video/mp4&lt;/code&gt;. Like the HTTP method and document path, the header value can be a simple wildcard &lt;code&gt;*&lt;/code&gt;. The wildcard is useful if you want to match against the presence of the header. Again, like the document path, the header value can be specified as a regular expression. The following example is useful for matching any video content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'content-type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TRegEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'video/.+'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you already have a &lt;code&gt;TStringList&lt;/code&gt; populated with headers, the &lt;code&gt;WithHeaders&lt;/code&gt; method can be used to match against all values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt;
  &lt;span class="n"&gt;LHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TStringList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="n"&gt;LHeaders&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TStringList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;LHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'content-type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;LHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'accept'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LHeaders&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Matching Body Content
&lt;/h1&gt;

&lt;p&gt;Matching by body content is where it can get a little more interesting. You can probably guess that we have a method called &lt;code&gt;WithBody&lt;/code&gt; that does pretty much exactly what you think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hello'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matching a pattern can be achieved with a regular expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TRegEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hello'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matching an exact string or pattern is all well and good, but when testing APIs, you're most likely dealing with some form of structured data. WebMocks provides several methods for dealing with two standard formats: form-data; and JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Matching Form Data
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;WithFormData&lt;/code&gt; method matches form-data values as submitted with the content-type &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithFormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'field'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'value'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, to match a RegEx pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithFormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'field'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TRegEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'pattern'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Matching JSON
&lt;/h2&gt;

&lt;p&gt;JSON data is more complicated as it has structure and typed values. To match a JSON attribute in the example content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Chester Copperpot"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following example will provide a positive match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Chester Copperpot'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overloaded versions of the &lt;code&gt;WithJSON&lt;/code&gt; method are defined to handle the data types in JSON: string, number (integer and decimal), and boolean. The JSON types of array and object are structural, and comparing them is not possible but navigating them is.&lt;/p&gt;

&lt;p&gt;If you have a deeply nested JSON structure that you want to match values against you can provide the first argument as &lt;a href="https://goessner.net/articles/JsonPath/"&gt;JSONPath&lt;/a&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'users[0].name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Chester Copperpot'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Putting it all together
&lt;/h1&gt;

&lt;p&gt;To demonstrate a more comprehensive example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/register'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithQueryParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'source'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'http://example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'content-type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'text/json'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'user.email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'ccopperpot@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'user.password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'goonie4ever'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'user.name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Chester Copperpot'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Created&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one example demonstrates the use of matching all HTTP message parts. While WebMocks provides an elegant and flexible interface for this, remember what the goal here is: identifying a request and responding appropriately to test some behaviour. To that end, maybe matching the document and method is enough?&lt;/p&gt;

&lt;p&gt;If you want to verify the request's format, you should look at "assertions". Luckily I have an upcoming article all about that "Asserting HTTP requests with WebMocks in Delphi". In the meantime, try &lt;a href="https://github.com/appercept/Delphi-WebMocks"&gt;WebMocks&lt;/a&gt; and &lt;a href="https://www.embarcadero.com/products/delphi"&gt;Delphi&lt;/a&gt; for yourself. The demos from this article and more are available on &lt;a href="https://github.com/appercept/Delphi-WebMocks-Demos"&gt;GitHub&lt;/a&gt;. Let me know how you get on in the comments below or on &lt;a href="https://twitter.com/RichHatherall"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>delphi</category>
      <category>testing</category>
      <category>tdd</category>
      <category>webmocks</category>
    </item>
    <item>
      <title>All about HTTP responses with WebMocks in Delphi</title>
      <dc:creator>Richard Hatherall</dc:creator>
      <pubDate>Mon, 15 Feb 2021 11:28:18 +0000</pubDate>
      <link>https://dev.to/rhatherall/all-about-http-responses-with-webmocks-in-delphi-2jfh</link>
      <guid>https://dev.to/rhatherall/all-about-http-responses-with-webmocks-in-delphi-2jfh</guid>
      <description>&lt;p&gt;In the previous post &lt;a href="https://dev.to/rhatherall/testing-http-clients-in-delphi-with-dunitx-and-webmocks-25ck"&gt;Testing HTTP clients in Delphi with DUnitX and WebMocks&lt;/a&gt; we looked at a DUnitX test's basic structure using &lt;a href="https://github.com/appercept/Delphi-WebMocks"&gt;WebMocks&lt;/a&gt; to stub an HTTP endpoint. At this point, it appears very simplistic and not at all like many real-world HTTP interactions. Most requests don't merely respond "OK" with no content. Let's explore how and what content we can mock, giving your test subjects scenarios allowing you to write tests asserting their behaviour.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Defaults
&lt;/h1&gt;

&lt;p&gt;When stubbing a request without specifying the response, the default is empty but successful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
content-type: text/plain; charset=utf-8
content-length: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This response differs from not stubbing the request only in status code which would be &lt;code&gt;501 Not Implemented&lt;/code&gt;. So, how do we customize the response? Using &lt;code&gt;ToRespond&lt;/code&gt; is the answer. Let's take a look at what we can do by chaining a &lt;code&gt;ToRespond&lt;/code&gt; call.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Status Codes
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;ToRespond&lt;/code&gt; function accepts an optional argument &lt;code&gt;AResponseStatus&lt;/code&gt; allowing you to specify the response status code. Returning a status of &lt;code&gt;204 No Content&lt;/code&gt; is achieved with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;204&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not all of us have a comprehensive knowledge of HTTP status codes, so, thankfully &lt;code&gt;ToRespond&lt;/code&gt; will accept an enum value instead, allowing you to have descriptive symbols in your test code without the need to add comments. Add &lt;code&gt;WebMock.ResponseStatus&lt;/code&gt; to your &lt;code&gt;uses&lt;/code&gt; clause, and you will be able to refer to status &lt;code&gt;204&lt;/code&gt; as &lt;code&gt;NoContent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll pause a moment here to point out some small syntactic sugar WebMocks provides: &lt;code&gt;WithStatus&lt;/code&gt;. By chaining &lt;code&gt;WithStatus&lt;/code&gt; after &lt;code&gt;ToRespond&lt;/code&gt; the test becomes more descriptive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;204&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// or
&lt;/span&gt;
&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NoContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;WithStatus&lt;/code&gt; also provides the ability to return a custom status code and text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;321&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Back In The Room'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we know how to change the response status. Unless you are returning &lt;code&gt;204 No Content&lt;/code&gt; however, you'll likely want to send some data back too. Let's take a look at setting the body content next.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Body Content
&lt;/h1&gt;

&lt;p&gt;As we saw earlier, the default response content is a zero-length plain-text response with the UTF-8 character set. Setting body content is done using &lt;code&gt;WithBody&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hello'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all well and good for plain-text, but you're quite likely to want to return something else like JSON. That's easy enough, specify a second argument with a content-type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'{ "key": "value" }'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we know how to respond with small snippets of data, what if we need something larger — or not easily represented in text? That's where &lt;code&gt;WithBodyFile&lt;/code&gt; comes in. You provide a path to a file, and WebMocks will attempt to return it with the correct content type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/video'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBodyFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'video.mp4'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, as with &lt;code&gt;WithBody&lt;/code&gt;, &lt;code&gt;WithBodyFile&lt;/code&gt; accepts a second argument for content-type if the file type is not commonly recognized or ambiguous.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/video'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBodyFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'video.3gp'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'video/3gpp'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Adding Headers
&lt;/h1&gt;

&lt;p&gt;When testing APIs, you will, at some point, need to respond with specific headers. For example in ReST API designs, it is common to return a &lt;code&gt;location&lt;/code&gt; header when creating a resource and responding &lt;code&gt;201 Created&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/resources'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'location'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'http://example.com/resources/1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can chain as many calls to &lt;code&gt;WithHeader&lt;/code&gt; as you like to build up a list of headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/resources/1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'cache-control'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'no-cache'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'last-modified'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Sat, 13 Feb 2021 12:45:26 GMT'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a convenience, seeing as it is common in Delphi to handle HTTP headers in a &lt;code&gt;TStringList&lt;/code&gt;, WebMocks provides &lt;code&gt;WithHeaders&lt;/code&gt; accepting a &lt;code&gt;TStrings&lt;/code&gt; instance. This allows you to populate a response with headers from an existing list of header values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt;
  &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TStringList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="n"&gt;Headers&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TStringList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'cache-control'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;'no-cache'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'last-modified'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;'Sat, 13 Feb 2021 12:45:26 GMT'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/resources/1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToRespond&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These previous two examples are identical in behaviour. While the call to &lt;code&gt;WithHeaders&lt;/code&gt; is a convenient short-hand if you already have a collection of headers built, I believe chaining calls to &lt;code&gt;WithHeader&lt;/code&gt; to be more descriptive when writing tests. Ultimately its a preference, you choose what works for you.&lt;/p&gt;

&lt;h1&gt;
  
  
  What we've learnt so far
&lt;/h1&gt;

&lt;p&gt;In the previous article, we saw how easy it is to set up a DUnitX project with WebMocks. In this article, we learnt how to customize HTTP responses with WebMocks using its HTTP-oriented interface methods. Give it a try in your projects and let me know how you get on in the comments or via &lt;a href="https://twitter.com/RichHatherall"&gt;Twitter&lt;/a&gt;. You can find the &lt;a href="https://github.com/appercept/Delphi-WebMocks-Demos"&gt;demo code on GitHub&lt;/a&gt;. The next part of this series will be along shortly "Matching HTTP requests with WebMocks in Delphi".&lt;/p&gt;

</description>
      <category>delphi</category>
      <category>testing</category>
      <category>tdd</category>
      <category>webmocks</category>
    </item>
    <item>
      <title>Testing HTTP clients in Delphi with DUnitX and WebMocks</title>
      <dc:creator>Richard Hatherall</dc:creator>
      <pubDate>Tue, 09 Feb 2021 09:54:24 +0000</pubDate>
      <link>https://dev.to/rhatherall/testing-http-clients-in-delphi-with-dunitx-and-webmocks-25ck</link>
      <guid>https://dev.to/rhatherall/testing-http-clients-in-delphi-with-dunitx-and-webmocks-25ck</guid>
      <description>&lt;p&gt;&lt;a href="https://www.embarcadero.com/products/delphi"&gt;Delphi&lt;/a&gt; makes writing HTTP client code easy. In Delphi, there are many choices to build on when writing an HTTP client, including two bundled options: &lt;a href="https://www.indyproject.org"&gt;Indy&lt;/a&gt;, and &lt;a href="http://docwiki.embarcadero.com/RADStudio/Sydney/en/Using_an_HTTP_Client"&gt;System.Net&lt;/a&gt;. It doesn't matter which way you go, the problems presented when testing it is the same — HTTP clients need a server with which to interact. If you don't control the server, you can't control the outcome. If you can't control the outcome, how do you know the results your test should produce?&lt;/p&gt;

&lt;p&gt;You might solve some of these issues by testing against a sandbox or testing environment. If you don't have these already, it can be a lot of work to set this up, and maybe it's not you providing the service? You might be depending on another team for building your backend. It might not be ready yet, and all you have is their documentation?&lt;/p&gt;

&lt;p&gt;Another solution is to run an in-process HTTP server within your test project. You get fine-grained control over the HTTP server, but the setup code can be a lot of effort hampering progress. Also, unless you carefully craft your test code, an HTTP server's setup code may obscure your tests intentions.&lt;/p&gt;

&lt;p&gt;With these issues in mind, I set about solving them by writing WebMocks for Delphi, freely available and open-source on &lt;a href="https://github.com/appercept/Delphi-WebMocks-Demos"&gt;GitHub&lt;/a&gt; and available through &lt;a href="https://getitnow.embarcadero.com/WebMocks-3.0/"&gt;GetIt&lt;/a&gt;. I designed WebMocks to integrate with DUnitX, the popular unit testing framework, also useful for running integration tests. WebMocks provides an in-process HTTP server with responses defined by an HTTP domain-specific-language interface.&lt;/p&gt;

&lt;p&gt;WebMocks allows you to focus on what's essential to your tests.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;You should make sure you have both DUnitX and WebMocks installed.&lt;br&gt;
If you installed RAD Studio/Delphi via the web installer, installing DUnitX is as simple as checking the box &lt;em&gt;DUnit Unit Testing Frameworks&lt;/em&gt; under &lt;em&gt;Additional Options&lt;/em&gt; in the &lt;em&gt;Platforms and Extensions Manager&lt;/em&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lbECs-hC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ibnp4w794925f5vspsh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lbECs-hC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ibnp4w794925f5vspsh3.png" alt="1. RAD Studio - Additional Options" width="631" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The quickest and easiest way to install WebMocks is via the GetIt Package Manager. Search for &lt;em&gt;WebMocks&lt;/em&gt; and click &lt;em&gt;Install&lt;/em&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rmrb4aUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s9pebrk4sd817yss3s15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rmrb4aUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s9pebrk4sd817yss3s15.png" alt="2. GetIt Package Manager" width="880" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at the most basic usage of WebMocks within a DUnitX test. We will use the &lt;code&gt;THTTPClient&lt;/code&gt; as the "class under test" so we don't need to write any additional classes. Testing an existing class like this will allow us to focus on the behaviour of WebMocks.&lt;/p&gt;

&lt;p&gt;Now, we can start setting up our project. Create a new DUnitX Project found under &lt;em&gt;File &amp;gt; New &amp;gt; Other.. &amp;gt; DUnitX&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Make sure &lt;em&gt;Create Test Unit&lt;/em&gt; and &lt;em&gt;Create Setup and TearDown Methods&lt;/em&gt; are selected. Give the TestFixture Class a name, such as &lt;em&gt;TBasicDemoTests&lt;/em&gt; and click "OK". Save your project and unit before continuing (Shift+Ctrl+S).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u6CvbnWF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1stph9jx2rsuz4nprd32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u6CvbnWF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1stph9jx2rsuz4nprd32.png" alt="3. New DUnitX Project" width="284" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to configure WebMocks in our TestFixture class: Add a private member &lt;code&gt;WebMock: TWebMock&lt;/code&gt; to the TestFixture class.&lt;/p&gt;

&lt;p&gt;Declare a member for the "class under test" too — &lt;code&gt;Client: THTTPClient&lt;/code&gt; in our example.&lt;/p&gt;

&lt;p&gt;Add the missing dependencies by adding &lt;code&gt;System.Net.HttpClient&lt;/code&gt; and &lt;code&gt;WebMock&lt;/code&gt; to your &lt;code&gt;uses&lt;/code&gt; block. You should initialise and clean up these dependencies in your &lt;code&gt;Setup&lt;/code&gt; and &lt;code&gt;TearDown&lt;/code&gt; procedures.&lt;/p&gt;

&lt;p&gt;You should now have a unit that looks like:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yxq8sK5H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cmigrv8qwz1lmc7isx4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yxq8sK5H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cmigrv8qwz1lmc7isx4k.png" alt="4. Ready" width="867" height="957"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you're ready to write some tests.&lt;/p&gt;
&lt;h1&gt;
  
  
  Writing your first test with WebMocks
&lt;/h1&gt;

&lt;p&gt;Let's add the most basic example of a WebMock stubbed request.&lt;/p&gt;

&lt;p&gt;Start by adding a new test procedure in the public section and complete your class by pressing Shift+Ctrl+C.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;procedure&lt;/span&gt; &lt;span class="n"&gt;Get_WhenStubbed_ReturnsOK&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We might write our test like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need a local variable to keep track of our HTTP interactions — &lt;code&gt;LResponse: IHTTPResponse&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Then we stub a "GET" request for the root path ("/").&lt;/li&gt;
&lt;li&gt;Then we call the client to perform a GET request and store the response.&lt;/li&gt;
&lt;li&gt;Finally, we check to see if the client received an "OK" response, represented by the HTTP status code &lt;code&gt;200&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight pascal"&gt;&lt;code&gt;&lt;span class="k"&gt;procedure&lt;/span&gt; &lt;span class="n"&gt;TBasicDemoTests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get_WhenStubbed_ReturnsOK&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt;
  &lt;span class="n"&gt;LResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IHTTPResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StubRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;LResponse&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's run it without debugging (Shift+Ctrl+F9) and see what happens.&lt;/p&gt;

&lt;p&gt;Now, if everything worked correctly, you should finally be able to see your test results:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--19JwI30L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fkncxs78edjj51yik4ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--19JwI30L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fkncxs78edjj51yik4ex.png" alt="6. Results" width="880" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Give WebMocks a try!
&lt;/h1&gt;

&lt;p&gt;WebMocks makes the tricky task of writing tests for HTTP clients simple. In the next in this series we learn all about HTTP responses with WebMocks in Delphi. You can find the &lt;a href="https://github.com/appercept/Delphi-WebMocks-Demos"&gt;code for this demo on GitHub&lt;/a&gt;. You can reach out to me on Twitter &lt;a href="https://twitter.com/RichHatherall"&gt;@RichHatherall&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>delphi</category>
      <category>testing</category>
      <category>tdd</category>
      <category>webmocks</category>
    </item>
  </channel>
</rss>
