

マルチポストしているのですがよろしくお願いします。  
<https://teratail.com/questions/c842khs7083hca>

以下の環境でlaravelとvue.jsでアプリ制作をしています。

  * MacOS
  * PHP 7.4.1
  * Laravel 6.20.26
  * PHPUnit 9.5.16

PHPunitでテストをした際に RegisterApiTest.php が通らない原因がわからないでいます。

RegisterApiTest.php

[code]

    <?php
    
    namespace Tests\Feature;
    
    use App\User;
    use Tests\TestCase;
    use Illuminate\Foundation\Testing\WithFaker;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    class RegisterApiTest extends TestCase
    {
        use RefreshDatabase;
    
        /**
         * @test
         */
        public function should_新しいユーザーを作成して返却する()
        {
            $data = [
                'name' => 'user',
                'email' => 'dummy@email.com',
                'password' => 'test1234',
                'password_confirmation' => 'test1234',
            ];
    (追記２でコメント機能解除)
    // dd($data);
            // 会員登録をroutes/api.php にルート定義
            // Route::post('/register', 'Auth\RegisterController@register')->name('register');
            // コントローラーの影響でここで @register　→　RegistersUsers トレイトの　register メソッド
            // 　→　@registeredが必要→registeredを書き込む。これによって$dataが登録用データとして送られる
            // RegisterController で registered メソッドの中身をオーバーライド
            // $dataを送る
    (追記２でコメント機能解除)
    // dd($response);
            $response = $this->json('POST', route('register'), $data);
    
    
            $user = User::first();
    (１回目のテスト,ここがエディターの３７行目に当たります)
            $this->assertEquals($data['name'], $user->name);
    (２回目のテストで上を省略)
          //$this->assertEquals($data['name'], $user->name);
    
            $response
    (ここが２回目のテストにおけるエディターの40行目に当たります)
                ->assertStatus(201)
                ->assertJson(['name' => $user->name]);
        }
    }
    
[/code]

これでテストを試したところ、ターミナルでは

**1回目のテスト**

[code]

    root@bf0269c31cae:/var/www/html# ./vendor/bin/phpunit tests/Feature/RegisterApiTest.php   
    PHPUnit 9.5.16 by Sebastian Bergmann and contributors.
    
    E                                                                   1 / 1 (100%)
    
    Time: 00:01.960, Memory: 22.00 MB
    
    There was 1 error:
    
    1) Tests\Feature\RegisterApiTest::should_新しいユーザーを作成して返却する
    ErrorException: Trying to get property 'name' of non-object
    
    /var/www/html/tests/Feature/RegisterApiTest.php:37
    
    ERRORS!
    Tests: 1, Assertions: 0, Errors: 1.
    
[/code]

ここからRegisterApiTest.phpの37行目でnameプロパティが、から（null?）なのだろうとまず考えました。

次に問題の37行目をコメント機能で消したところ

**２回目のテスト**

[code]

    :/var/www/html# ./vendor/bin/phpunit tests/Feature/RegisterApiTest.php 
    PHPUnit 9.5.16 by Sebastian Bergmann and contributors.
    
    F                                                                   1 / 1 (100%)
    
    Time: 00:03.398, Memory: 22.00 MB
    
    There was 1 failure:
    
    1) Tests\Feature\RegisterApiTest::should_新しいユーザーを作成して返却する
    Expected status code 201 but received 405.
    Failed asserting that false is true.
    
    /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:186
    /var/www/html/tests/Feature/RegisterApiTest.php:40
    
    FAILURES!
    Tests: 1, Assertions: 1, Failures: 1.
    
[/code]

このことからresponseが上手く行っていないことからエラーが出るのでは？と判断して、ルーティングとメソッドを見に行きました。

APIのためにルーティングを少し変更しています。

app/Providers/RouteServiceProvider.php を以下のようにしました。

[code]

    protected function mapApiRoutes()
    {
        Route::prefix('api')
    //  'api' → 'web' に変更
             ->middleware('web') 
             ->namespace($this->namespace)
             ->group(base_path('routes/api.php'));
    }
    
[/code]

apiに関するルーティングはroutes/api.php(routes/web.phpではありません)に書き込んで

routes/api.php

[code]

    <?php
    
    use Illuminate\Http\Request;
    
    // 会員登録
    Route::post('/register', 'Auth\RegisterController@register')->name('register');
    
[/code]

メソッドはsrc/app/Http/Contorollers/auth/RegisterController.phpに以下を記述しています。

[code]

    コード
    protected function registered(Request $request, $user)
        {
            return $user;
        }
    
[/code]

どこで見落としているのかがわからないでいます。よろしくお願いします‍♂️

### 追記

laravel6.0での  
$response = $this->json('POST', route('register'), $data);  
の書き方がおかしいのかな？と考えたのですが、６系のドキュメントにおいて

<https://readouble.com/laravel/6.x/ja/http-tests.html>

以下のようにあったので、ここは問題ないと思います。

[code]

    public function testBasicExample()
        {
            $response = $this->json('POST', '/user', ['name' => 'Sally']);
    
            $response
                ->assertStatus(201)
                ->assertExactJson([
                    'created' => true,
                ]);
        }
    
[/code]

PHPUnit.xml

[code]

    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="DB_CONNECTION" value="sqlite_testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="DB_CONNECTION" value="sqlite"/>
        <server name="DB_DATABASE" value=":memory:"/>
        <server name="MAIL_DRIVER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
      </php>
    
[/code]

config/database.php

[code]

    'connections' => [
    //追加
            'sqlite_testing' => [
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
            ],
    
[/code]

追記２  
dd()を利用して調べてみたのですがコメントが長すぎることもあるので重要そうな部分を抜粋して載せて行きたいと思います‍♂️dd()の場所とその内容は上記のテストコードにわかりやすいように記述しておきたいと思います。

[code]

    dd($data);の場合
    
    root@bf0269c31cae:/var/www/html# ./vendor/bin/phpunit tests/Feature/RegisterApiTest.php
    PHPUnit 9.5.16 by Sebastian Bergmann and contributors.
    
    array:4 [
      "name" => "user"
      "email" => "dummy@email.com"
      "password" => "test1234"
      "password_confirmation" => "test1234"
    ]
    root@bf0269c31cae:/var/www/html#
    
    
      dd($response);の場合
    
    lluminate\Foundation\Testing\TestResponse^ {#1169
      +baseResponse: Illuminate\Http\JsonResponse^ {#1209
        #data: """
          {\n
              "message": "The POST method is not supported for this route. Supported methods: GET, HEAD.",\n
              "exception": "Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException",\n
              "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php",\n
              "line": 256,\n
              "trace": [\n
                  {\n
                      
    
    
        """
        #version: "1.0"
        #statusCode: 405
        #statusText: "Method Not Allowed"
        #charset: null
        +original: array:5 [
          "message" => "The POST method is not supported for this route. Supported methods: GET, HEAD."
          "exception" => "Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException"
          "file" => "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php"
          "line" => 256
          "trace" => array:32 [
          
    
    
     +exception: Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException^ {#1185
          -statusCode: 405
          -headers: array:1 [
            "Allow" => "GET, HEAD"
          ]
          #message: "The POST method is not supported for this route. Supported methods: GET, HEAD."
          #code: 0
          #file: "./vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php"
          #line: 256
          trace: {
    
    
       ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:442 { …}
            ./tests/Feature/RegisterApiTest.php:34 {
              Tests\Feature\RegisterApiTest->should_新しいユーザーを作成して返却する()^
              › // dd($data);
              › $response = $this->json('POST', route('register'), $data);
              › 
              arguments: {
                $method: "POST"
                $uri: "http://localhost/127.0.0.1/api/register"
                $data: array:4 [ …4]
              }
            }
    
    
       }
      }
      #streamedContent: null
    }
    root@bf0269c31cae:/var/www/html# 
    
    
[/code]


CC BY-SA 4.0
2022-03-10T01:08:54.383
86774
2022-03-10T12:13:37.717
2022-03-10T11:07:04.587
51643
51643
question
php laravel vue.js phpunit
PHPUnitでのテストにおいて登録を確認するテストのresponseが上手くいかず、エラーが出てしまう


ヘルパ関数 `route()` はURL を生成します。  
<https://readouble.com/laravel/6.x/ja/helpers.html#method-route>

[code]

    $response = $this->json('POST', route('register'), $data);
    
[/code]

`json` メソッドの二番目の引数を `'api/register'` に改めるといかがでしょうか？


CC BY-SA 4.0
2022-03-10T07:21:18.263
86782
2022-03-10T07:21:18.263
51722
86774
answer


自己解決しました。

追記２内の `$uri: "http://localhost/127.0.0.1/api/register"` が明らかにおかしいことに気づき、元々
`127.0.0.1` が記述されていた箇所を以下の通り変更したらとりあえず通りました。

**変更前:**

[code]

    REDIS_HOST=127.0.0.1
    APP_URL=127.0.0.1
    
[/code]

**変更後:**

[code]

    REDIS_HOST=db (dockerのmysqlに接続)
    APP_URL=
    
[/code]

なのでどちらかの `127.0.0.1` が原因となってurlでおかしくなって通らなかったのだと思われます。ありがとうございました‍♂️


CC BY-SA 4.0
2022-03-10T11:20:31.003
86786
2022-03-10T12:13:37.717
2022-03-10T12:13:37.717
3060
51643
86774
answer