-
-
Notifications
You must be signed in to change notification settings - Fork 501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mocking Uuid::uuid4() in laravel #147
Comments
Update: I'm not ignoring your question; I've been dealing with moving, the holidays, death in family, and lack of Internet connectivity over the past few weeks. I hope to address your question later this week. :-) |
@ramsey thank you for taking the time to respond, I am sorry to hear about your loss. I hope you and your family had a great holiday. Take care. |
In #23, the OP couldn't mock Ramsey\Uuid\Uuid because the class was marked Here's an example I've whipped up and tested, so I know either of these approaches will work. Let me know if you have any questions or need clarification. <?php
use PHPUnit\Framework\TestCase;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidFactory;
class UuidMockTest extends TestCase
{
public function testKnownUuidByMockingFactory()
{
// Create a Uuid object from a known UUID string
$stringUuid = '253e0f90-8842-4731-91dd-0191816e6a28';
$uuid = Uuid::fromString($stringUuid);
// Partial mock of the factory;
// returns $uuid object when uuid4() is called.
$factoryMock = \Mockery::mock(UuidFactory::class . '[uuid4]', [
'uuid4' => $uuid,
]);
// Replace the default factory with our mock
Uuid::setFactory($factoryMock);
// Uuid::uuid4() is a proxy to the $factoryMock->uuid4() method, so
// when Uuid::uuid4() is called, it calls the mocked method on the
// factory and returns a valid Uuid object that we have defined.
$this->assertSame($uuid, Uuid::uuid4());
$this->assertEquals($stringUuid, Uuid::uuid4()->toString());
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testMockStaticUuidMethodToReturnKnownString()
{
// We replace the Ramsey\Uuid\Uuid class with one created by Mockery
// (using the "alias:" prefix) so that we can mock the static uuid4()
// method. For this to work without affecting the Ramsey\Uuid\Uuid
// class used by other tests, we must run this in a separate process
// with preserveGlobalState disabled (see method annotations).
\Mockery::mock('alias:' . Uuid::class, [
'uuid4' => 'uuid-baz',
]);
// We've replaced Ramsey\Uuid\Uuid with our own class that defines the
// method uuid4(). This method returns the string "uuid-baz."
$this->assertEquals('uuid-baz', Uuid::uuid4());
}
} |
@cmosguy Did my answer help? |
@ramsey thanks for taking the time for writing a very clear test in your response. This is super informative and helpful. I am now able to use this in my workflow. I had no clue you could trick phpunit like that Thanks for the super support! |
This is how I mocked it
This is how I called UUID generator in my class |
Also don't forget to do:
after your tests are done so you don't mess up other tests/code that uses Uuid |
The other day I encountered a similar problem in a project, because the default factory was overwritten inside For me, relying on the |
This is how I did this thanks to baopham/laravel-dynamodb#10 (comment) and #147 (comment) use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidFactory;
$defaultFactory = Uuid::getFactory();
$requestId = $this->faker->uuid;
// Partial mock of the factory
// returns $uuid object when uuid4() is called.
$factoryMock = \Mockery::mock(UuidFactory::class . '[uuid4]', [
'uuid4' => Uuid::fromString($requestId),
]);
Uuid::setFactory($factoryMock);
// set back to default
Uuid::setFactory($defaultFactory); |
One more approach if you have multiple calls to the Uuid factory in the tested code but only care about the next single/few of them:
Then in your test case:
|
Hey @ramsey ,
I am trying to create a uuid that is predictable for a specific integration test where I am hitting a route in Laravel and I generate some thumbnails based on the created user uuid. I am struggling on figuring out how to create a Mockery object that will just return the Uuid::uuid4()->toString() method with a known fake value.
Here is what I have in my eloquent model in Larave User.phpl:
Then my controller is doing this when creating a user:
So my integration test is going something I want to just setup top in the test:
You can see the
tn-$size-uuid-baz-now.jpeg
that is the name of thumnbail that is generated after I create the user. I want in my test to set the output ofUuid:uuid4()
touuid-baz
so that my other tests will work when generating the names of the thumbnails for the user.I know this is long winded question but I am struggling to figure out how to swap in and control the output.
Have you ever played with Carbon? Check this out they have a testing aid:
http://carbon.nesbot.com/docs/#api-testing
There is a way to set the
now()
method:Is there an easy way to do this for Uuid? If not, it's ok just going on a tangent here which is a nice to have here.
The text was updated successfully, but these errors were encountered: