Request in PhpUnit using Laravel 5.1 - unit-testing

I'm testing my Rest APIs.
I want to pass a parameter to my request.
This is in my controller, I have:
public function index(Request $request)
{
$abuse = Abuse::where('bombId', $request->input('bombId'))->get();
}
Thing is with PhpUnit, I can never simulate the bombId parameter...
Here is my code:
$data['bombId'] = 25; // I also tried $bombId = 25;
$this->get('api/v1/abuse', $data])
->seeJson(['total' => 11]);
$this->assertResponseStatus(200);
EDIT:
When I use:
$this->call('GET','api/v1/abuse', $credentials);
Param is passed, but I can't use anymore SeeJson method :(
Any Idea?

I found my answer with Jeffrey Way:
$response = $this->call('GET', 'api/v1/abuse', $credentials);
$data = $this->parseJson($response);
$this->assertIsJson($data);
$this->assertEquals(11, $data->total);

Related

Spock interaction verification ignoring call to Mock method

The following Spock test is failing to not counting the call to the Mock method:
def setup() {
mojo = new PactCreateVersionTagMojo()
mojo.pactBrokerUrl = 'http://broker:1234'
mojo.pacticipant = 'test'
mojo.pacticipantVersion = '1234'
mojo.tag = 'testTag'
}
def 'calls pact broker client with mandatory arguments'() {
given:
mojo.brokerClient = Mock(PactBrokerClient)
when:
mojo.execute()
then:
notThrown(MojoExecutionException)
1 * mojo.brokerClient.createVersionTag(
'test', '1234', 'testTag')
}
You can find it here.
The SUT code, removing the argument validation code, is:
class PactCreateVersionTagMojo : PactBaseMojo() {
override fun execute() {
...
createVersionTag()
}
private fun createVersionTag() =
brokerClient!!.createVersionTag(pacticipant!!, pacticipantVersion.orEmpty(), tag.orEmpty())
You can find it here.
The error is as follows:
I have a very similar example on the same project that passes just fine:
def 'passes optional parameters to the pact broker client'() {
given:
mojo.latest = 'true'
mojo.to = 'prod'
mojo.brokerClient = Mock(PactBrokerClient)
when:
mojo.execute()
then:
notThrown(MojoExecutionException)
1 * mojo.brokerClient.canIDeploy('test', '1234',
new Latest.UseLatest(true), 'prod') >> new CanIDeployResult(true, '', '')
}
override fun execute() {
...
val result = brokerClient!!.canIDeploy(pacticipant!!, pacticipantVersion.orEmpty(), latest, to)
}
You can find the test above here and the SUT here.
I have investigated the call that happens during the test, and it seems as expected.
Additionally, I try to create the verification with wildcard argument constraints, but it still didn't work.
It seems to me that I have misconfigured my test, but I can't spot the difference between the test that passes and my failing test.
Your fun createVersionTag(..) looks like this:
fun createVersionTag(
pacticipant: String,
pacticipantVersion: String,
tag: String) {
}
I do not speak Kotlin, but I think you ought to open the method because otherwise it is final, which means it cannot be overridden by a subclass and thus not be mocked or stubbed by conventional means. This is also the difference to open fun canIDeploy(..).

with() and leftjoin() in Laravel

How can I use both with() and leftjoin() in Laravel eloquent? I would like to use in below code.
$applicants = Applicant::with('applicant_skill')->paginate();
You can use whereHas
$query = Applicant::whereHas('applicant_skill', function ($q) {
$q->where('name', 'PHP');
})
->paginate(10);

undefined method FatalThrowableError::getStatusCode() - Testing Laravel 5.2

I'm starting to look into testing so thought id do something simple like see if a page loads correctly.
Here is my test;
<?php
use App\Users\Models\User;
class BlogPostsTest extends TestCase {
protected $baseUrl = 'http://localhost:8000';
public function testBlogPostsAreAccessible()
{
$this->be( User::findOrFail(1) );
$response = $this->call( 'GET', '/admin/blog-posts' );
$this->assertEquals( 200, $response->getStatusCode() );
}
}
Which returns and error
1) BlogPostsTest::testBlogPostsAreAccessible Error: Call to undefined
method
Symfony\Component\Debug\Exception\FatalThrowableError::getStatusCode()
/Users/ss/git/modules/admin/admin-blog/app/Exceptions/Handler.php:77
/Users/ss/git/modules/admin/admin-blog/app/Exceptions/Handler.php:58
/Users/ss/git/modules/admin/admin-blog/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:291
/Users/ss/git/modules/admin/admin-blog/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:107
/Users/ss/git/modules/admin/admin-blog/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:515
/Users/ss/git/modules/admin/admin-blog/tests/ExampleTest.php:12
FAILURES! Tests: 1, Assertions: 0, Errors: 1.
The error is coming from $this->call() does anyone know why this is?
regards
Are you sure your 'admin/blog-posts' returns an actual response object? Can you dd() the output in your test? So:
dd($response);
To see what it is your code is returning?

Unite Test: Serialization of 'Symfony\Component\HttpFoundation\File\UploadedFile' is not allowed

I'm trying to write white test to test my API with file uploads.
I'm following the docs about this using basic client request, not crawler.
The unit test is:
class RecordsControllerTest extends WebTestCase {
private $client;
public function __construct() {
parent::__construct();
$this->client = self::createClient();
$this->client->insulate();
}
public function testApiPostUpload($params){
$fileToUpload = realpath(__DIR__.'/../../resources/mpthreetest.mp3');
$file = new UploadedFile(
$fileToUpload,
'mpthreetest.mp3',
MimeTypeGuesser::getInstance()->guess($fileToUpload),
filesize($fileToUpload)
);
$this->client->request('POST', '/records/'.$params['createdRecordId'].'/upload', array(), array('file' => $file) );
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}
}
When I execute the test I receive an error:
Exception: Serialization of 'Symfony\Component\HttpFoundation\File\UploadedFile' is not allowed
/path/to/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php:165
/path/to/project/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php:348
/path/to/project/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Client.php:143
/path/to/project/vendor/symfony/symfony/src/Symfony/Component/BrowserKit/Client.php:313
/path/to/project/src/Bundle/Tests/Functional/Controller/RecordsControllerTest.php:182
I have found this question for about the same error, but in this case the request is not sent to the controller and the problem is not the entity and implementing serialization.
Anyone who knows how to fix this?
Anyone who managed to make unit test for uploading file in symfony 2?
You could try to NOT insulate the requests passing false as argument to the insulate method so try this:
$this->client->insulate(false);
instead of this:
$this->client->insulate();
Hope this help
I was able to resolve it by setting the changeHistory parameter to false (7th and last parameter in the request method signature):
$crawler = $client->request($form->getMethod(), $form->getUri(), $values, $files, [], null, false);
This will prevent the serialize on following lines :
if ($this->followRedirects && $this->redirect) {
$this->redirects[serialize($this->history->current())] = true;
return $this->crawler = $this->followRedirect();
}

phpunit mock web service(not WSDL)

I have a small problem which I think is quite simple to solve for experienced PHPUnit users.
I'm working with ZF2.
I'm working with a web service that returns plain text(CSV). I'd like to unit test the service that I've created.
I currently have a working configuration which is not the right way to do it I think.. I'm using mocks now when I'm unit testing my models and I have seen that PHPUnit has a special mock for web services, but that only supports WSDL.
Beneath you'll find my code and I hope someone can help me out with some explanation about the best practice for this situation.
The docs and the topics out here did not help me out (yet).
Thanks in advance!
The test itself:
public function testCanSearchSteeringWheels()
{
// Create the entry and fill it with the data that should be retrieved from the web service
$steeringWheelEntity = new SteeringWheelEntity();
$steeringWheelEntity->setId('170633')
->setName('Nice steering wheel one')
->setGrossPrice(100)
->setNetPrice(75);
// Setup the http client which whill make the final call to the web service
$httpClient = new Client();
$httpClient->setOptions(array(
'maxredirects' => 5,
'timeout' => 60,
))
->setAuth($this->config['supplier_name']['api']['username'], $this->config['supplier_name']['api']['password'])
;
$steeringWheelService = new SteeringWheelService($httpClient, new Request(), $this->config['supplier_name']);
// Search for a steering wheel by id code
$searchResult = $steeringWheelService->search('ID=5221552658987');
$this->assertEquals($steeringWheelEntity, $searchResult[0]);
}
The SteeringWheelEntity
namespace SupplierName\Entity;
class SteeringWheelEntity
{
// vars
// exchange array method
// getters methods
// setters methods
}
The SteeringWheelService
namespace SupplierName\Service;
use SupplierName\Entity\SteeringWheelEntity;
class SteeringWheelService extends AbstractWebService
{
/**
* search()
*
* #param string $param
* #return array
*/
public function search($param)
{
$this->appendUrl('ww0800?3,' . $param);
$response = $this->dispatch();
$parsedBody = $this->parse($response->getBody());
$entities = array();
foreach ($parsedBody as $data)
{
$steeringWheel = new SteeringWheelEntity();
// Fill SteeringWheelEntity with data
$entities[] = $steeringWheel;
}
return $entities;
}
}
The AbstractWebService
use \Zend\Http\Client;
use \Zend\Http\Request;
class AbstractWebService
{
private $httpClient;
private $request;
private $response;
protected $config;
private $url;
public function __construct(Client $httpClient, Request $request, Array $config)
{
$this->url = $config['api']['url'];
$this->httpClient = $httpClient;
$this->request = $request;
$this->config = $config;
}
protected function setUrl($url)
{
$this->url = $url;
return $this->url;
}
protected function appendUrl($string)
{
$this->url .= $string;
}
protected function getUrl()
{
return $this->url;
}
public function dispatch()
{
$this->request->setUri($this->getUrl());
$this->response = $this->httpClient->dispatch($this->request);
if (!$this->response->isSuccess()) {
throw new \Exception('HTTP error #' . $this->response->getStatusCode() . ' when connecting to ' . $this->getUrl() . '.');
}
return $this->response;
}
public function parse()
{
// Parse the content
}
}
Rather than using a mock for a web service. Could you just mock the \Zend\Http\Request and \Zend\Http\Client objects as they are doing the work for you? This way you have control over what the Zend objects return to you versus having to try to mock the web service.
That would be how I would go about testing the services.