Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP mock data from rest endpoint

I'm writing a PHP wrapper around a third party API. More so for practice, but I also don't see a good one available anywhere at the moment so maybe it'll be used by others in the future.

My unit tests have been quite simple, except now I have hit a limit.

The developer of the API has got a max requests limit (1 per second, 20 per minute), and my unit tests are accessing the API endpoints via my API wrapper, hence testing my wrapper. However running phpunit has started to return a 429 too many requests error. Phpunit is obviously therefore running the 15 or so tests I have, all of which are accessing the endpoints too quickly and giving me this error.

Does anybody know if I a) should be mocking these responses, and b) how I would mock the responses if i'm testing my wrapper?. What good are tests if they're not running on my actual wrapper object and surely I don't want to be making my wrapper use mock responses?

I am new to unit testing, I feel very uncomfortable with the idea at the moment, however I'm beginning to warm to it!

like image 704
Simon Willan Avatar asked Mar 28 '16 18:03

Simon Willan


1 Answers

Very good question! It's a common problem when you're new to testing.

Firstly, make a distinction between unit and integration testing:

  • unit testing - testing a "unit", most often a class, in isolation. It's achieved by mocking or stubbing unit's dependencies most of the time. No infrastructure (network, filesystem etc) should be used at this level.
  • integration testing - testing how components interact with each other. You might hit the infrastrcuture, but you can still choose not to (to optimise).

I'd do the following:

  • Implement the API client as a library and write integration tests for it. These integration tests will actually hit the API and will prove the client interacts with the API as expected. I'd run them whenever the API client changes, or periodically to make sure I'm still compatible with the API. These tests wouldn't be run as often as the application tests, as they'd be part of a separate test suite.
  • Introduce an abstraction in the app that will let me to provide alternative implementations for whatever interacts with the API. This way I'd be able to write acceptance or other kind of integration tests with a simpler implementation (for example an in-memory one).
  • Make sure that if I'm making an assumption in the app for how the API client works, I've got an integration tests proving this assumption is correct. For example, if I call a method with a valid ID, it returns an object. Otherwise it throws an exception. I can rely on these rules only if I've got an integration test somewhere verifying them.

Mocking responses is a tricky business. If you try doing it one day you'll run into troubles when the 3rd party API changes. If you still want to go this path, have a look at https://github.com/coduo/tutu.

like image 126
Jakub Zalas Avatar answered Nov 04 '22 09:11

Jakub Zalas