Question

below is my controller class and the relevant method and my test class and relevant test. when the mocked method $this->user->update() runs I get this error

Time: 1.08 seconds, Memory: 31.00Mb

There was 1 error:

1) UserControllerTest::testUpdateSuccess
ErrorException: Argument 1 passed to Mockery_818785360_User::update() must be of
 the type array, string given, called in C:\Users\Mark\Dropbox\www\trainercompar
e\app\controllers\UsersController.php on line 134 and defined

shouldnt the mocked method take whatever arguments I send it unless otherwise defined? even if I change the mocked object method to include with(m::type'string') I get the same error. Ultimately the first argument will be a string and the second will be an array but I cant even get that far yet.

UserController.php

class UsersController extends BaseController {

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }


    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
        $user = $this->user->find($id);

        if ($id == Auth::user()->id) {

            $input = Input::all();

            $validation = $this->user->validate($input);

            if ($validation->passes()) {

                $this->user->update(); 

            }


        }
        else {
            echo 'update failed';
        }
    }


}

UserControllerTest.php

<?php
    use Mockery as m;
    use Way\Tests\Factory;
class UserControllerTest extends TestCase {

    public function setUp()
    {
        parent::setUp();
        $this->mock = m::mock('Basemodel', 'User');
    }

    public function tearDown()
    {
        m::close();
    }


    public function testUpdateSuccess()
    {
        $input = ['email' => 'john@doe.com',
                'password' => 'johndoepw',
                'firstName' => 'john',
                'secondName' => 'doe',
                'dob' => '1985-12-12',
                'height' => '187.96',
                'gender' => 'm',
                'phone' => '0877777777',
                'postcode' => '01',
                'addOne' => '29 black market',
                'addTwo' => 'malahide',
                'townCity' => 'Dublin',
                'county' => 'Dublin',
                'country' => 'Ireland'
                ];

        $userid = m::mock('userid');
        $userid->id = '1';
        $view = m::mock('viewret');
        $valmock = m::mock(['passes' => true]);

        Auth::shouldReceive('user')
            ->times(1)
            ->andReturn($userid);

        $this->mock
            ->shouldReceive('find')
            ->times(1)
            ->andReturn($userid->id);

        //Input::shouldReceive('all')->times(1);

        $this->mock
            ->shouldReceive('validate')
            ->times(1)
            ->andReturn($valmock);

        $this->mock
            ->shouldReceive('update')
            ->withAnyArgs()
            ->times(1);

        $this->app->instance('User', $this->mock);
        $this->call('Put', 'users/1', $input);
        $this->assertResponseOk();
    }

}
Was it helpful?

Solution

(mockery instance)->shouldReceive only validates the arguments after the function is run. So, in your controller code:

if ($validation->passes()) {
  $this->user->update(); 
}

You're not actually passing anything to the update function. I'm assuming you want to pass in $input. so, it should be $this->user->update($input);

I'm assuming that your instance of user has a method update that requires an array be passed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top