zunkt's avatar
Level 2

Unit Test with mockery HttpResponseException response

Hi everyone! I'm new in mockery to unit test and I want to test a function like this:

 public function failedValidation(Validator $validator)
    {
        $response['errors'] = $validator->errors();
        throw new HttpResponseException(
            response()->json(['message' => $response['errors']], 400)
        );
    }

So I use this: setUp:

	protected function setUp(): void
    {
        parent::setUp();
        $this->getAccessTokenRequest = m::mock(GetAccessTokenRequest::class);
    }

Test

        // Test failed validation
        $error = new HttpResponseException(new Response('this is a test', 400));
        $this->getAccessTokenRequest->shouldReceive('failedValidation')->andThrow($error);

I think maybe it's wrong but I don't know how to do that. Please help me. Thanks so much.

0 likes
3 replies
Tray2's avatar

I usually do something like this to test my validations

   public function setUp():void
    {
        parent::setUp();
        $this->signIn();
        Genre::factory()->create([
            'genre' => 'Fantasy'
        ]);
    }

      /**
     * @test
     * @dataProvider genreValidationProvider
     * @param $field
     * @param $fieldValue
     */
    public function genre_validations($field, $fieldValue)
    {
        $genre = Genre::factory()->make([
            $field => $fieldValue
        ]);

        $this->post('/genres', $genre->toArray())
            ->assertStatus(302)
            ->assertSessionHasErrorsIn($field);
    }

    public function genreValidationProvider()
    {
        return [
            'genre is required' => ['genre', ''],
            'genre must be unique' => ['genre', 'Fantasy'],
            'media_type_id is required' => ['media_type_id', '']
        ];
    }

zunkt's avatar
Level 2

@Tray2 Do u often use mockery for test Controller code like this:

	$userName = $query->leftJoin('shop', 'users.shop_id', 'shop.id')
            ->where('shop.deleted_at', null)
            ->where('users.status', 'pending')
            ->where('shop.start_date', '<=', $now)
            ->where('shop.expire_date', '>=', $now)
            ->where('user.username', $username)
            ->select('users.name')
            ->first();

SetUp

	protected function setUp(): void
    {
        parent::setUp();
        $this->user = m::mock(User::class);
    }

Test:

	$this->user->shouldReceive('leftJoin')
            ->once()
            ->with('shop', 'users.shop_id', 'shop.id')
            ->andReturnSelf()
            ->shouldReceive('where')
            ->with('shop.deleted_at', null)
            ->andReturnSelf()
            ->shouldReceive('where')
            ->with('users.status', 'Pending')
            ->andReturnSelf()
            ->shouldReceive('where')
            ->with('shop.start_date', '<=' , $now)
            ->andReturnSelf()
            ->shouldReceive('where')
            ->with('username', '<=' , 'user1')
            ->andReturnSelf()
            ->shouldReceive('select')
            ->with('users.name')
            ->andReturnSelf()
            ->shouldReceive('first')
            ->andReturn($username);
Tray2's avatar
Tray2
Best Answer
Level 74

@zunkt I never use Mock for testing my queries.

I have this query in one of my apps

 public function index()
    {
        $books = BookView::orderBy('author_name')
                         ->orderBy('series_started')
                         ->orderBy('part')
                         ->orderBy('released')
                         ->orderBy('title')
                         ->get();
        return view('books.index')->with(['books' => $books, 'type' => 'books']);
    }

And to test the sorting I do this

/**
    * @test
    */
    public function when_listing_all_books_they_are_alphabetically_sorted_by_authors_last_name()
    {
        $jordan = Author::factory()->create([
            'last_name' => 'Jordan',
            'first_name' => 'Robert'
        ]);
        $terry = Author::factory()->create([
            'last_name' => 'Goodkind',
            'first_name' => 'Terry'
        ]);
        $sarah = Author::factory()->create([
            'last_name' => 'Ash',
            'first_name' => 'Sarah'
        ]);

        $bookJordan = Book::factory()->create();
        $bookTerry = Book::factory()->create();
        $bookSarah = Book::factory()->create();

        AuthorBook::factory()->create([
            'book_id' => $bookTerry->id,
            'author_id' => $terry->id
        ]);
        AuthorBook::factory()->create([
            'book_id' => $bookJordan->id,
            'author_id' => $jordan->id
        ]);
        AuthorBook::factory()->create([
            'book_id' => $bookSarah->id,
            'author_id' => $sarah->id
        ]);
        $response = $this->get('/books');

        $response->assertSeeInOrder([
            'Ash, Sarah',
            'Goodkind, Terry',
            'Jordan, Robert'
        ]);
    }

  /**
    * @test
    */
    public function books_by_the_same_author_is_sorted_by_relase_year()
    {
        $author = Author::factory()->create([
            'last_name' => 'Goodkind',
            'first_name' => 'Terry'
        ]);

        $book1 = Book::factory()->create([
            'title' => 'The Law Of Nines',
            'released' => 2009
        ]);

        $book2 = Book::factory()->create([
            'title' => 'The Wizards First Rule',
            'released' => 1994
        ]);

        $book3 = Book::factory()->create([
            'title' => 'Nest',
            'released' => 2016
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book1->id,
            'author_id' => $author->id
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book2->id,
            'author_id' => $author->id
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book3->id,
            'author_id' => $author->id
        ]);

        $response = $this->get('/books');

        $response->assertSeeInOrder([
            'The Wizards First Rule',
            'The Law Of Nines',
            'Nest'
        ]);
    }

   /**
    * @test
    */
    public function books_in_the_same_series_is_sorted_by_the_first_book_in_the_series_release_year_then_by_part()
    {
        $author = Author::factory()->create([
            'last_name' => 'Goodkind',
            'first_name' => 'Terry'
        ]);

        $book1 = Book::factory()->create([
            'title' => 'The Law Of Nines',
            'series' => 'Standalone',
            'released' => 2009
        ]);

        $book2 = Book::factory()->create([
            'title' => 'The Wizards First Rule',
            'series' => 'The Sword Of Truth',
            'part' => 1,
            'released' => 1994
        ]);
        $book3 = Book::factory()->create([
            'title' => 'The Stone Of Tears',
            'series' => 'The Sword Of Truth',
            'part' => 2,
            'released' => 2010
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book1->id,
            'author_id' => $author->id
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book2->id,
            'author_id' => $author->id
        ]);

        AuthorBook::factory()->create([
            'book_id' => $book3->id,
            'author_id' => $author->id
        ]);


        $response = $this->get('/books');

        $response->assertSeeInOrder([
            'The Wizards First Rule',
            'The Stone Of Tears',
            'The Law Of Nines',
        ]);
    }
1 like

Please or to participate in this conversation.