I am trying to test via phpunit laravel cache (file driver). My test body:
namespace Tests\Feature;
use Illuminate\Support\Facades\Cache;
use Tests\TestCase;
use Closure;
class CacheTestTest extends TestCase
{
public function testCache()
{
Cache::shouldReceive('remember')
->once()
->with(md5(1), 120, Closure::class)
->andReturn('Closure');
}
}
When I am running test, I get error:
Method remember('c4ca4238a0b923820dcc509a6f75849b', 120, 'Closure') from Mockery_0_Illuminate_Cache_CacheManager should be called exactly 1 times but called 0 times.
What am I doing wrong? Where to get docs about shouldReceive and what I must put to the andReturn ?
Thanks for replies!
EDIT:
The code creates Carbon object and then check if it exist.
public function testCache()
{
$key = md5(1);
$duration = 120;
$object = Cache::remember( $key, $duration, function () {
return Carbon::today();
});
Cache::shouldReceive('get')
->with($key, $duration, \Closure::class)
->andReturn($object);
}
CodePudding user response:
The code creates Carbon object and then check if it exist.
public function testCache()
{
$key = md5(1);
$duration = 120;
$object = Cache::remember( $key, $duration, function () {
return Carbon::today();
});
Cache::shouldReceive('get')
->with($key, $duration, \Closure::class)
->andReturn($object);
}
CodePudding user response:
So, I can give some tips based on the test you added to your question:
- You are trying to test if
Cache
works - You want to check if calling
Cache
with the right parameters works
So:
- Your test makes no sense at all, because you are testing if
Cache
works, and it does! It is shipped by the framework itself, so of course it is working. If you want to test a specific caching part of your code, that is fine, but just callingCache
and then checking if it cached, that test adds no value at all - Instead of having
Cache::shouldReceive(...)->...
after theCache::remember
(the part you want to test), you have to move that BEFORE you call it, because you are literally caching the value on your test environment, but then you are saying "if something callsCache->get
with$key
,$duration
and\Closure::class
, then return$object
.
To have 2.
fixed, you have to use this code (instead of using a Mock, use a Spy, this is what Laravel says about Spies):
use WithFaker;
public function testCache()
{
$key = $this->faker->uuid();
$duration = $this->faker->numberBetween(1, 120);
$spy = Cache::spy();
Cache::remember(
$key,
$duration,
function () {
return today();
}
);
$spy->shouldHaveReceived('remember')
->once()
->with($key, $duration, \Mockery::type('callable'));
}
You can read more about the difference between a Mock and a Spy, but the long story short is that a Mock will mock what it will return when a certain method of a certain class with more conditions (or not) is met what to return or do, but a Spy will spy (assert) if those conditions were met AFTER you run your code.