如何在phpunit模拟中模拟请求方法?

时间:2019-03-16 05:09:41

标签: php laravel phpunit

我开始使用嘲讽,所以在进行单元测试时遇到了问题。我想测试身份验证中间件,我为expectsJson传递了一个条件,因此我需要另一个模式来从expectesJson返回true,如下所示,但不成功

Authenticate.php

protected function redirectTo($request)
{
    if (! $request->expectsJson()) {
        return route('login');
    }
}

AuthenticatTest.php

class AuthenticateTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     */
    public function testMiddleware()
    {
      $request = Request::create(config('app.url') . '500', 'GET',[],[],[],['REMOTE_ADDR'=>'127.0.0.1:8000']);
      $middleware = new Authenticate($this->createMock(Factory::class));
      $class = new \ReflectionClass(Authenticate::class);
      $method = $class->getMethod("redirectTo");
      $method->setAccessible(true);
      $expectedStatusCode = 401;
      $this->assertContains("http://",$method->invokeArgs($middleware,[$request]));
    }

    public function testMiddlewareElse()
    {
      $this->mock(Request::class, function($mock) {
        $mock->shouldReceive("expectsJson")
          ->once()->andReturn(true);
      });

      $request = Request::create(config('app.url') . '200', 'POST',[],[],[],['REMOTE_ADDR'=>'127.0.0.1:00']);
      $middleware = new Authenticate($this->createMock(Factory::class));
      $class = new \ReflectionClass(Authenticate::class);
      $method = $class->getMethod("redirectTo");
      $method->setAccessible(true);
      $this->assertContains("",$method->invokeArgs($middleware,[$request]));
    }
}
  

testMiddlewareElse失败,如何为$request->expectsJson返回true

2 个答案:

答案 0 :(得分:0)

这是测试身份验证中间件请求的方法。假设您有一条需要认证的路由,该路由由UserController@dashboard(或类似名称)管理:

public function testMiddleware() {
      // You could disable the other middleware of the route if you don't want them to run e.g.
      // $this->withoutMiddleware([ list of middleware to disable ]);
      $mockController = $this->prophecy(UserController::class);
      //This is if the middleware passes and the controller method is called, use shouldNotBeCalled if you expect it to fail 
      $mockController->dashboard(Prophecy::any())->shouldBeCalled();
      $this->app->instance(
         UserController::class, 
         $mockController->reveal()
      );
      $this->json("GET", url()->action("UserController@dashboard"));
}

答案 1 :(得分:-1)

我找到了解决方案!我需要在调用参数中传递模拟类...;)

public function testMiddlewareElse()
{
  $mock = $this->mock(Request::class, function($mock) {
    $mock->shouldReceive("expectsJson")
      ->once()->andReturn(true);
  });

  $request = Request::create(config('app.url') . '200', 'POST',[],[],[],['REMOTE_ADDR'=>'127.0.0.1:00']);
  $middleware = new Authenticate($this->createMock(Factory::class));
  $class = new \ReflectionClass(Authenticate::class);
  $method = $class->getMethod("redirectTo");
  $method->setAccessible(true);
  $this->assertContains("",$method->invokeArgs($middleware,[$mock]));
}