I'm currently building a Laravel package that injects a new method in Illuminate\Http\Request
via Macros. The method I'm injecting has been completed and is expected to work nicely, but I also want to test it before releasing it.
My test requires me to change the request's Accept
header, in order for me to see if the test is passing or no. So I have done the following to simulate the request:
// package/tests/TestCase.php namespace Vendor\Package; use Illuminate\Http\Request; use Orchestra\Testbench\TestCase as Orchestra; abstract class TestCase extends Orchestra { /** * Holds the request * @var Illuminate\Http\Request */ protected $request; /** * Setup the test */ public function setUp() { parent::setUp(); $this->request = Request::capture(); $this->request->headers->set('Accept', 'application/x-yaml'); } }
Then in my test I use the method I'm injecting into Request
with $this->request->wantsYaml()
and it's always returning false since the Accept
header is not getting set to application/x-yaml
.
class RequestTest extends TestCase { /** @test */ public function it_should_return_a_bool_if_page_wants_yaml_or_not() { dump($this->request->wantsYaml()); // Return false $this->assertTrue($this->request->wantsYaml()); // It fails! } }
How do I go on simulating the headers in a test in Laravel package development?
EDIT
This is my YamlRequest
class
use Illuminate\Http\Request; use Illuminate\Support\Str; class YamlRequest extends Request { /** * Acceptable content type for YAML. * @var array */ protected $contentTypeData = ['/x-yaml', '+x-yaml']; /** * Determine if the current request is asking for YAML in return. * * @return bool */ public function wantsYaml() { $acceptable = $this->getAcceptableContentTypes(); // If I dd($acceptable), it comes out as empty during tests! return isset($acceptable[0]) && Str::contains($acceptable[0], $this->contentTypeData); } }
So I literally have to simulate the Accept in order to see if my wantsYaml
method is working as expected.
Use Laravel Unit Testing to Avoid Project-Wrecking Mistakes. Pardeep Kumar. 7 Min Read. PHPUnit is one of the most well known and highly optimized unit testing packages of PHP. It is a top choice of many developers for rectifying different developmental loopholes of the application.
For developers, Laravel can be used with Angular JS for developing large single page web applications.
A partially mocked object would allow you to test your Illuminate\Http\Request::macro
without also testing ancillary methods within Laravel's Illuminate\Http\Request
object. In other words, all you really need to know is that your macro works. You don't need to test that a Request
can be constructed and that its headers can be set.
In the following tests, I'll setup a "partially" mocked version of your YamlRequest
object using Mockery.
Partial mocks are useful when we only need to mock several methods of an object leaving the remainder free to respond to calls normally (i.e. as implemented).
See the Mockery Documentation, Creating Partial Mocks.
The partial mock will allow us to mock the methods from Laravel's Request
object while leaving your macro free to run as it would in a production environment.
use YamlRequest; use \Mockery; class RequestTest extends TestCase { public function setUp() { parent::setUp(); $this->request = Mockery::mock(YamlRequest::class)->makePartial(); } public function test_that_wants_yaml_returns_true_given_x-yaml_accept_header() { /** * This line allows you to control the return value of * Illuminate\Http\Request::getAcceptableContentTypes while your macro * is running. */ $this->request->allows( [ 'getAcceptableContentTypes' => ['application/x-yaml', 'text/html'] ] ); $this->assertTrue($this->request->wantsYaml()); } public function test_that_wants_yaml_returns_false_given_json_accept_header() { $this->request->allows( [ 'getAcceptableContentTypes' => ['application/json', 'text/html'] ] ); $this->assertFalse($this->request->wantsYaml()); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With