L. Fox
L. Fox

Reputation: 354

Pass request through method in test

I have a generate() method on my class which is just a shorthand way to create an instance of the class. It accepts a request which is type hinted on the method. I am trying to unit test this and the only way I know how is to make an answer and pass that through. That doesn’t work tho because it is not a request. Is there a work around for this? Here is the method:

public static function generate(Question $question, Request $request): self
    {
        return self::create([
            'user_id' => Auth::user()->getKey(),
            'question_id' => $question->getKey(),
            'answer_body' => $request->answer_body,
        ]);
    }

Here is the test

/** @test */
    public function it_can_generate_a_new_instance()
    {
        $user = factory(User::class)->create();
        $this->actingAs($user);

        $question = factory(Question::class)->create();
        $answer = factory(Answer::class)->make();

        Answer::generate($question, $answer);

        $this->assertEquals($user->getKey(), Answer::first()->user_id);
        $this->assertEquals($question->getKey(), Answer::first()->question_id);
        $this->assertEquals($answer->answer_body, Answer::first()->answer_body);
    }

The test passes until I type hint Request in the method.

Upvotes: 0

Views: 486

Answers (2)

Mathieu Ferre
Mathieu Ferre

Reputation: 4412

a request should only be present on a controller, and not in the Model Answer (Or you will encounter errors like that ^^)

If your process require a request, then you should test an http request instead :


/** @test */
    public function it_can_generate_a_new_instance()
    {

       $user = factory(User::class)->create();
        $this->actingAs($user);

        $question = factory(Question::class)->create();
        $answer = factory(Answer::class)->make();

        $this->post(route('answer.store'), $answer->toArray());

        // Then your answer will be generated in your controller

        $this->assertEquals($user->getKey(), Answer::first()->user_id);
        $this->assertEquals($question->getKey(), Answer::first()->question_id);
        $this->assertEquals($answer->answer_body, Answer::first()->answer_body);

    }

Upvotes: 0

apokryfos
apokryfos

Reputation: 40653

You can make a new request object with the given property. It's probably a bit flimsy but it should work:

public function it_can_generate_a_new_instance()
{
    $user = factory(User::class)->create();
    $this->actingAs($user);

    $question = factory(Question::class)->create();
    $answer = factory(Answer::class)->make();
    $request = new Request([ 'answer_body' => $answer->answer_body ]);

    Answer::generate($question, $request);

    $this->assertEquals($user->getKey(), Answer::first()->user_id);
    $this->assertEquals($question->getKey(), Answer::first()->question_id);
    $this->assertEquals($answer->answer_body, Answer::first()->answer_body);
}

Upvotes: 1

Related Questions