N
N
nepster-web2017-07-20 16:05:37
PHP
nepster-web, 2017-07-20 16:05:37

What is the correct approach to testing a php client working through a third party API?

Description of the system
There is a third-party API through which the PHP application works. Imagine the most common PHP project, only a third-party API is used instead of its own database.
Briefly about the architecture
The architecture is divided into several layers, the lowest layer is Request, which receives data from the API. Conventionally, I will call the 2nd layer View Model (a certain class with getters) that Request returns. The next layers are Presenter and Repository.
Work cycle
For example, the constructor pulls the Repository inside which the Request receives the necessary View Model and wraps it in the Presenter .
For reference: Presenter - a kind of wrapper for the View Model, in order to change methods (a kind of decorator)
Data for testing
Since our client has practically no business logic, all tests will be reduced to ensuring that data is received and rendered correctly. At the same time, the client does not have its own database, so all possible results from the API will be prepared in advance in json files.
Goal
To test all layers in such a way as to guarantee the correct operation of the client with the data that got into it.
Approach Using the Content
module as an example, I will try to describe my thoughts on testing this stuff. ContentRequestTest.php The first thing we will try to test is that

Request does indeed return the View Model we need .

public function test_request_getRecord(): void
    {
        $responseDataArray = $this->getArrayFromJsonFile('content/Record.json');
        $contentRequest = new ContentRequestMock($responseDataArray['data'], [], 200);

        $record = $contentRequest->getRecord();
        $this->assertInstanceOf(Record::class, $record);
    }

ContentViewPresenterTest.php
Next, we will test the Presenter . The Presenter descends directly into the views, so each of its fields needs to be checked.
public function test_RecordPresenter(): void
    {
        $responseDataArray = $this->getArrayFromJsonFile('content/Record.json');
        $contentRequest = new ContentRequestMock($responseDataArray['data'], [], 200);

        $presenter = new RecordPresenter($contentRequest->getRecord());

        $this->assertInternalType('string', $presenter->getDate());
        $this->assertInternalType('string', $presenter->getLabel());
        $this->assertInternalType('string', $presenter->getCategory());

        $this->assertEquals($presenter->getUrl(), route('journal.show', ['alias' => 'record-alias']));
        $this->assertEquals($presenter->getPreviewDefaultImage(), 'preview_url_1.jpeg');
        $this->assertEquals($presenter->getReviewDefaultImage(), 'preview_url_1.jpeg');
        $this->assertEquals($presenter->getTitle(), 'title');
        $this->assertEquals($presenter->getShortText(), 'text_short');
        $this->assertEquals($presenter->getFullText(), 'text_full');
    }

ContentRepositoryTest.php
Lastly, we will test the Repository . Does it really return the required Repository to us
public function test_repository_getRecord(): void
    {
        $contentRepository = $this->buildRepositoryFromJsonFile('content/Record.json');
        $record = $contentRepository->getRecord('record-alias');

        $this->assertInstanceOf(ContentRepository::class, $contentRepository);
        $this->assertInstanceOf(ContentRepositoryContract::class, $contentRepository);

        $this->assertInstanceOf(RecordPresenter::class, $record);
        $this->assertInstanceOf(RecordPresenterContract::class, $record);
    }

QUESTIONS
1. - Have I chosen the right approach to testing?
2. - The tests are independent and can be executed in any order, however, because of this, you have to do the same operations in each test for connecting mocks, does it make sense to cram it all into 1 file, and not split into 3?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question