Delphi makes writing HTTP client code easy. In Delphi, there are many choices to build on when writing an HTTP client, including two bundled options: Indy, and System.Net. 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?
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?
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.
With these issues in mind, I set about solving them by writing WebMocks for Delphi, freely available and open-source on GitHub and available through GetIt. 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.
WebMocks allows you to focus on what's essential to your tests.
You should make sure you have both DUnitX and WebMocks installed.
If you installed RAD Studio/Delphi via the web installer, installing DUnitX is as simple as checking the box DUnit Unit Testing Frameworks under Additional Options in the Platforms and Extensions Manager.
Let's take a look at the most basic usage of WebMocks within a DUnitX test. We will use the
THTTPClient 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.
Now, we can start setting up our project. Create a new DUnitX Project found under File > New > Other.. > DUnitX.
Make sure Create Test Unit and Create Setup and TearDown Methods are selected. Give the TestFixture Class a name, such as TBasicDemoTests and click "OK". Save your project and unit before continuing (Shift+Ctrl+S).
Next, we need to configure WebMocks in our TestFixture class: Add a private member
WebMock: TWebMock to the TestFixture class.
Declare a member for the "class under test" too —
Client: THTTPClient in our example.
Add the missing dependencies by adding
WebMock to your
uses block. You should initialise and clean up these dependencies in your
Now you're ready to write some tests.
Let's add the most basic example of a WebMock stubbed request.
Start by adding a new test procedure in the public section and complete your class by pressing Shift+Ctrl+C.
[Test] procedure Get_WhenStubbed_ReturnsOK;
We might write our test like this:
- We need a local variable to keep track of our HTTP interactions —
- Then we stub a "GET" request for the root path ("/").
- Then we call the client to perform a GET request and store the response.
- Finally, we check to see if the client received an "OK" response, represented by the HTTP status code
procedure TBasicDemoTests.Get_WhenStubbed_ReturnsOK; var LResponse: IHTTPResponse; begin WebMock.StubRequest('GET', '/'); LResponse := Client.Get(WebMock.URLFor('/')); Assert.AreEqual(200, LResponse.StatusCode); end;
Let's run it without debugging (Shift+Ctrl+F9) and see what happens.
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 code for this demo on GitHub. You can reach out to me on Twitter @RichHatherall.