stringContains argument matching within Laravel Lo

2020-04-02 02:57发布

I saw in the Laravel docs that it's possible to set a test expectation like this:

Cache::shouldReceive('get')
                ->once()
                ->with('key')
                ->andReturn('value');

Then I saw in the PHPunit docs that flexible argument matching is possible like this: $this->stringContains('Something').

But when I edit my test to have this:

Log::shouldReceive('error')
            ->once();
            ->with($this->stringContains('Contact does not exist'));

...then I get the following error:

Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Log_Writer::error("Contact does not exist blah blah etc"). 
Either the method was unexpected or its arguments matched no expected argument list for this method

How can I accomplish my goal (with flexible argument matching within Log::shouldReceive)?

P.S. I've also tried ->with(\PHPUnit\Framework\Assert::stringContains('Contact does not exist')).

1条回答
forever°为你锁心
2楼-- · 2020-04-02 03:30

The mocking functionality of facades uses Mockery to generate mock objects. stringContains() is functionality provided by PHPUnit mock objects. These two are not compatible.

You will need to use argument validation methods provided by Mockery.

My first attempt would be to use the \Mockery::pattern() matcher which uses regular expressions:

Log::shouldReceive('error')
    ->once();
    ->with(\Mockery::pattern('/Contact does not exist/'));

Another option would be to use the \Mockery::on() matcher, which allows you to use a Closure to provide complex argument matching logic.

Log::shouldReceive('error')
    ->once();
    ->with(\Mockery::on(function ($arg) {
        return stripos($arg, 'Contact does not exist') !== false;
    }));
查看更多
登录 后发表回答