Reputation: 183
if my data that passes to view has structure like this:
[
'foo' => [
'a' => 1,
'b' => 2,
],
'bar' => [
'c' => 3,
'd' => 4,
],
]
how can I write a test for this, that assert this array should have foo,a,b,bar... keys?
it likely checks the structure of array, but since assertjsonstructure() method exist only for json response I can not use this method for this issue.
to make it easy understand what I need here my code:
public function show($slug): View
{
$post = Post::whereStatus('RELEASED')
->whereSlug($slug)
->firstOrFail();
$permissions['access_to_edit'] = FALSE;
$permissions['access_to_delete'] = FALSE;
return view('post.news.show',compact('post','permissions'));
}
/**
* @test
*/
public function news_can_be_shown()
{
$this->withoutExceptionHandling();
$post = PostFactory::released()->withImage()->create();
$response = $this->get(route('news.show',['slug' => $post->slug]))
->assertOk()
->getOriginalContent()
->getData();
// I need something like this:
$response->assertArrayStruct([
'post' => [
'id','main_title','secondary_title',...
],
'permissions' => [
'access_to_edit','access_to_delete'
]
]);
// But so far I have not been able to write anything better than this:
$this->assertEquals($news->id,$response['post']['id']);
$this->assertEquals($news->main_title,$response['post']['main_title']);
$this->assertEquals($news->secondary_title,$response['post']['secondary_title']);
$this->assertEquals($news->context,$response['post']['context']);
$this->assertEquals($news->slug,$response['post']['slug']);
$this->assertEquals($news->user->name,$response['post']['user']['name']);
$this->assertEquals($news->image->path,$response['post']['image']['path']);
$this->assertEquals($news->comment,$response['post']['comment']);
$this->assertEquals($news->like,$response['post']['like']);
$this->assertEquals($news->dislike,$response['post']['dislike']);
$this->assertEquals($news->view,$response['post']['view']);
$this->assertEquals($news->created_at,$response['post']['created_at']);
}
Upvotes: 2
Views: 496
Reputation: 8102
Your test is not far away from what you want, but I am going to show you the right way for this.
First of all, some tips:
route('name')
because you are testing that the desired route exists, so if you write asdasdsd
as your news.show
, here in the test it will pass, but it will not when you go to the desired URL, so hardcode your URL in the test and never use route
helper.$this->withoutExceptionHandling();
, never leave it in a test, only use it for testing errors (and fixing them)->getOriginalContent()....
as there are methods for testing anything you want from the response, so write in your mind to never use getOriginalContent
again (you will see with my code).Now, your test should be like this:
/**
* @test
*/
public function news_can_be_shown()
{
$post = PostFactory::released()->withImage()->create();
$response = $this->get("/your/route/{$post->slug}");
$response->assertOk();
$response->assertViewHas('post', $post);
$response->assertViewHas(
'permissions',
function (array $permissions) {
return $permissions['access_to_edit'] === false &&
$permissions['access_to_delete'] === false;
}
);
}
If you want more precision, you can modify any of those 2 functions and do any check, the only condition is that the function must return true
(if it has what you want) or false
(did not pass assertion).
More info about assertViewHas
and also see the source code as the documentation is not showing what I did, but if you see the source code, it can accept what I passed as the second argument.
If you want to know more or add any more tests, edit your question and I will gladly edit my answer too.
Upvotes: 2