0

In my application, I have a service that uses a function related to a model.

This function has already been tested (on its Unit Test), and in my Feature test, I just need to "use" its output value.

Because this function is "complicated", I would mock its value without warry about what the function does. This is the scenario:

Model

class MyModel
{
    public function calculateSomething()
    {
        // Implementation, already unit tested
        // Here i put some "crazy" logic (this is not real :) )
        if ($this->field_a < 10 || $this->field_b > 15) {
          return true;
        }

        if ($this->field_c !== null || $this->field_e < 50) {
           return false;
        }

        return true;
    }
}

In my Service i dont need to re-create those conditions, i just need to say "in this test calculateSomething will return true", dont care why it return true

Service

class MyService
{
    public function myMethod($id)
    {
        $models = MyModel::all();

        foreach($models as $model) {
            if ($model->calculateSomething()) {
                // Do domething here
            } else {
                // Do other stuff here
            }
        }
    }

    public function myMethodIsolated($model)
    {
        if ($model->calculateSomething()) {
            // Do domething here
        } else {
            // Do other stuff here
        }
    }
}

Usually, I mock service, but I never mock a function inside a model, it's possible to mock the function calculateSomething ?

In my example, I provided an isolated version of the function, called myMethodIsolated where I pass the single instance.

Mistre83
  • 2,677
  • 6
  • 40
  • 77
  • Could you add more information about what `calculateSomething` would do? I think there is "something wrong", something seems off. You should never _mock_ a `Model`, as that could hide/not run code that is based on events or similar... explain more what that method is doing, maybe we can encapsulate it even more. – matiaslauriti Dec 07 '21 at 03:18
  • the `calculateSomething`is a function that is simple to unit test, because i can create all the conditions to test it. In a feature test, I don't need to re-create these conditions, but I just need to use its return value to test the logic. – Mistre83 Dec 10 '21 at 14:12
  • This code is untestable. `Model::all` will return a lot of instances and you are calling it in the service itself which does not give you the opportunity to fully or partially mock them. The best you can do is use a factory to craft your data in such a way that your function returns `true` but that will mean you function code will execute. In Laravel, factories are the way to "mock" data. If you still want to mock your models you will need to change your `myMethod` to take the model collection as an argument and mock each model in your test before passing it – apokryfos Dec 12 '21 at 07:56

0 Answers0