简体   繁体   中英

How to mock a Validation Rule in Laravel

I want to mock a custom Validation rule (eg App\\Rules\\SomeRule). But when I run my test, it gives an Mockery\\Exception\\InvalidCountException: Method...should be called exactly 1 times but called 0 times.

I've read Laravel's documentation on Mocking , on custom Validation Rules , Service Containers , Service Providers and I cannot figure out why I'm not successfully mocking the rule.

I read this thread but I'm struggling to connect it with my problem which is, "How can I test that my app is using this Rule". Or is that something I cannot test?

Here's my Rule

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class SomeRule implements Rule
{

    public function passes($attribute, $value)
    {
        // some logic, returns TRUE if valid.
    }

    public function message()
    {
        //
    }
}

My controller

namespace App\Http\Controllers;

use App\Rules\SomeRule;
use Illuminate\Http\Request;

class LoanController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'email' => ['required', new SomeRule]
        ]);

        // ...insert in database, return json.
    }
}

My Test

namespace Tests\Feature;

use Mockery;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Rules\SomeRule;

class LoansTest extends TestCase
{
    use RefreshDatabase;

    public function tearDown(): void
    {
        parent::tearDown();
        Mockery::close();
    }

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

        $rule = Mockery::mock(SomeRule::class)->shouldReceive('passes')->once();
        $this->app->instance(SomeRule::class, $rule);

        $response = $this->json('POST', '/api/loans', ['email' => 'whatevs@gmail.com']);
    }
}

I played with the idea of registering SomeRule in the AppServiceProvider. But that still didn't do anything:

    public function register()
    {
        $this->app->bind(SomeRule::class, function ($app) {
            return new SomeRule();
        });
    }

Code in Github

you need to use like this

class LoanController extends Controller
{
    public function store(Request $request)
    {
      $request->validate([
        'email' => ['required', new SomeRule()]
      ]);

    // ...insert in database, return json.
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM