Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Incremental APISs: Refactoring Tests and Traits
<?php
use Faker\Factory as Faker;
abstract class ApiTester extends TestCase {
/**
* @var Faker
*/
protected $fake;
/**
* Initialize
*/
function __construct()
{
$this->fake = Faker::create();
}
/**
* Setup database for each test
*/
public function setUp()
{
parent::setUp();
$this->app['artisan']->call('migrate');
}
/**
* Get JSON output from API
*
* @param $uri
* @param string $method
* @param array $parameters
* @return mixed
*/
protected function getJson($uri, $method = 'GET', $parameters = [])
{
return json_decode($this->call($method, $uri, $parameters)->getContent());
}
/**
* Assert object has any number of attributes
*
*/
protected function assertObjectHasAttributes()
{
$args = func_get_args();
$object = array_shift($args);
foreach ($args as $attribute)
{
$this->assertObjectHasAttribute($attribute, $object);
}
}
}
<?php
trait Factory {
/**
* @var int
*/
protected $times = 1;
/**
* Number of times to make entities
*
* @param $count
* @return $this
*/
protected function times($count)
{
$this->times = $count;
return $this;
}
/**
* Make a new record in the DB
*
* @param $type
* @param array $fields
* @throws BadMethodCallException
*/
protected function make($type, array $fields = [])
{
while ($this->times--)
{
$stub = array_merge($this->getStub(), $fields);
$type::create($stub);
}
$this->times = 1;
}
/**
* @throws BadMethodCallException
*/
protected function getStub()
{
throw new BadMethodCallException('Create your own getStub method to declare your fields.');
}
}
<?php
class LessonsTest extends ApiTester {
use Factory;
/** @test */
public function it_fetches_lessons()
{
$this->make('Lesson');
$this->getJson('api/v1/lessons');
$this->assertResponseOk();
}
/** @test */
public function it_fetches_a_single_lesson()
{
$this->make('Lesson');
$lesson = $this->getJson('api/v1/lessons/1')->data;
$this->assertResponseOk();
$this->assertObjectHasAttributes($lesson, 'body', 'active');
}
/** @test */
public function it_404s_if_a_lesson_is_not_found()
{
$json = $this->getJson('api/v1/lessons/x');
$this->assertResponseStatus(404);
$this->assertObjectHasAttributes($json, 'error');
}
/** @test */
public function it_creates_a_new_lesson_given_valid_parameters()
{
$this->getJson('api/v1/lessons', 'POST', $this->getStub());
$this->assertResponseStatus(201);
}
/** @test */
public function it_throws_a_422_if_a_new_lesson_request_fails_validation()
{
$this->getJson('api/v1/lessons', 'POST');
$this->assertResponseStatus(422);
}
protected function getStub()
{
return [
'title' => $this->fake->sentence,
'body' => $this->fake->paragraph,
'some_bool' => $this->fake->boolean
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.