Ad

How To Mock User Model Within Composer Package Development Tests?

I started creating a laravel 5.8 based modular API framework for our company which should be extended using composer packages.

Now I stumbled over the problem to test each package by itself (each package has it's own GIT project of course) if the package needs to have access to the User model given in the base framework (App/Models/User).

There will be various packages naturally depending on the User model such as specific auth modules.

Unfortunately testing also gets more complex because we are using GraphQL (Lighthouse).

So how should this be done? I tried mocking App/Models/User with a User model contained in the tests folder of my package, but this did not work as expected:

$this->userMock = \Mockery::mock('CompanyName\\PackageName\\Tests\\User');

$this->app->instance('App\\Models\\User', $this->userMock);

When, after that, posting a GraphQL request the resolver method throws a Class App\Models\User does not exist error.

I am quiet new to testing with phpunit so maybe I am just missing something here?

Edit: I just found out that the error message above is displayed because the User model is also referenced within the GraphQL schema file. So I there is any solution out there it has to somehow "emulate" the not existing User model class for the whole request lifecycle I guess...

Ad

Answer

Ok I finally solved my problem which was more conceptual wise I guess. As the user model is pretty strongly tied to the (core) package I want to test, I have now moved the model into the package itself and removed it from the base project. This has the advantage that the "end user developer" doesn't even see and has to cope with the user model which is handles by the package anyway.

Now I can test the package independently and only have to put a line of documentation into the README to tell, that a user has to change the auth.providers.users.modelvalue to let laravel use the appropriate model (e.g. CompanyName\\PackageName\\Models).

If there will be other packages extending the user model, they will have to depend on the core package (which they should either way) and can extend the model class and tell the user to update auth.providers.users.model again. This way it is also quiet transparent to see which user model is used currently.

For the GraphQL / Lighthouse part I have added the following code to the boot method of the package's service provider to make lighthouse know about new models within the package automatically:

$lighthouseModels = config('lighthouse.namespaces.models');
array_push($lighthouseModels, 'CompanyName\\PackageName\\Models');

config([
   'lighthouse.namespaces.models' => $lighthouseModels
]);

This can be repeated for every package adding models as well so lighthouse knows about all of them.

Ad
source: stackoverflow.com
Ad