Thread overview
[Unit tests] Mocking D objects
Aug 22, 2018
Andrey
Aug 22, 2018
Simen Kjærås
Aug 22, 2018
Andre Pany
Aug 24, 2018
Jesse Phillips
August 22, 2018
Hello,
I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects?
For example:
>struct WebParser
>{
>    // ...
>
>    int download(string path)
>    {
>        SomeHttpClient client(path);
>        auto result = client.request(path, 10, "Qwerty");
>
>        // ...
>
>        return result.getSomething();
>    }
>}

Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe:
unittest
{
    SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient);

    WebParser parser;
    auto value = parser.download("www.example.com"); // uses MyMockedClient.request
    assert(value == 10);

}
August 22, 2018
On Wednesday, 22 August 2018 at 08:33:36 UTC, Andrey wrote:
> Hello,
> I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects?
> For example:
>>struct WebParser
>>{
>>    // ...
>>
>>    int download(string path)
>>    {
>>        SomeHttpClient client(path);
>>        auto result = client.request(path, 10, "Qwerty");
>>
>>        // ...
>>
>>        return result.getSomething();
>>    }
>>}
>
> Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe:
> unittest
> {
>     SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient);
>
>     WebParser parser;
>     auto value = parser.download("www.example.com"); // uses MyMockedClient.request
>     assert(value == 10);
>
> }

The language itself does not offer mocking capabilities. However, there are excellent libraries in Dub:

https://code.dlang.org/packages/unit-threaded
https://code.dlang.org/packages/dmocks

--
  Simen
August 22, 2018
On Wednesday, 22 August 2018 at 08:33:36 UTC, Andrey wrote:
> Hello,
> I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects?
> For example:
>>struct WebParser
>>{
>>    // ...
>>
>>    int download(string path)
>>    {
>>        SomeHttpClient client(path);
>>        auto result = client.request(path, 10, "Qwerty");
>>
>>        // ...
>>
>>        return result.getSomething();
>>    }
>>}
>
> Here I want to replace struct/class SomeHttpClient from 3d-party library with my own test implementation. Something like this maybe:
> unittest
> {
>     SomeMagicMockMechanism!(SomeHttpClient, MyMockedClient);
>
>     WebParser parser;
>     auto value = parser.download("www.example.com"); // uses MyMockedClient.request
>     assert(value == 10);
>
> }

You could also create an interface IHttpClient, a class HttpClientProductive which forwards the calls to SomeHttpClient and a class HttpClientDummy which can be instrumented which data it should return in unit test case. Both classes implements the interface.
You also need a way to set the productive class for productive scenario and the dummy class in test scenario, e.g. via a factory class.

There is a huge benefit using this way, you have a very loose coupling to SomeHttpClient. You can replace it very easily with another library.

You could use this approach also for file system access, environment variables access, databases...

Kind regards
Andre
August 24, 2018
On Wednesday, 22 August 2018 at 08:33:36 UTC, Andrey wrote:
> Hello,
> I know that D has build-in unit tests. If so, what mechanism D provides for mocking objects?

I'd like to pose the question, what are you testing. This looks like you are testing that your mocked object returns 10. I usually try to make functions more pure like.