Summer Sale! All accounts are 50% off this week.

jivanrij's avatar

Doing clean POST calls in tests with XML bodies

Currently, I'm writing tests in which I need to post XML to my API endpoints. I discovered that Laravel doesn't like XML. And as far as I can see there are no out-of-the-box handy test methods to work with within tests. The only way to post XML in the body within a test is like this:

$this->call('POST', 'http://endpoint.api', [], [], [], [], '<xml>my xml</xml>');

I was wondering if there is a cleaner way of doing this just like it's possible to work with JSON like this example:

$this->post('http://endpoint.api', ['name' => 'Sally'])

The HTTP facade makes the following possible. But this does the call outside the scope of the test (and the transaction) and results in changes to the database.

Http::withBody('<xml>my xml</xml>', 'text/xml')->post('http://endpoint.api');

I would prefer to use JSON but in my case, this is not up to me. I expect there are a lot more developers that need to work with XML and write tests for it.

0 likes
2 replies
jivanrij's avatar
jivanrij
OP
Best Answer
Level 5

Due to count($post->reactions) === 0, I guess there is no real nice solution to this. Currently, I've solved it by adding a method in Tests/TestCase. Something like this:

    /**
     * Calls a route with a POST call and a given body.
     *
     * @param  string  $route
     * @param  string  $body
     * @param  array  $routeParams
     *
     * @return TestResponse
     */
    protected function postXml(string $route, string $body = '', array $routeParams = []): TestResponse
    {
        return $this->call('POST', route($route, $routeParams), [], [], [], [], $body);
    }

This is a stripped version of what I use in my scenario. In my case, I've also got some header variables and stuff like that making the helper a bit more useful. When looking at the stripped example here you could argue creating a helper can be a bit overkill. It depends on your coding style I guess.

Billit's avatar

My solution was this

Added this function in Testcase

public function postXml($uri, $xmlBody, array $headers = [])
{
    $headers = array_merge($headers, ['Content-Type' => 'text/xml;charset=utf-8']);
    $server = $this->transformHeadersToServerVars($headers);
    return $this->call('POST', $uri, [], [], [], $server, $xmlBody);
}

and after that I could call it like this

$this->postXml(route('peppol.webhook'),$xmlBody);
1 like

Please or to participate in this conversation.