flyingL123's avatar

Mocked class in another test treated as though it exists

Using Laravel 5.8, I have the following 2 tests within the same test class:

/**
 * @test
 */
public function a_procurement_group_can_be_created_or_fetched_from_odoo_for_this_shipment()
{
    $shipment = InboundShipment::make();

    $group = $this->mock(ProcurementGroup::class, function($group) {
        $group->shouldReceive('findByNameOrCreate')
            ->with('foo')
            ->andReturnSelf();
    });

    $this->assertSame($group, $shipment->getProcurementGroup('foo'));
}

/**
 * @test
 */
public function a_procurement_can_be_created_for_an_item_in_the_shipment()
{
    $shipment = InboundShipment::make();

    $group = app(ProcurementGroup::class);

    $procurement = app(ProcurementOrder::class);

    $item = $this->mock(InboundShipmentItem::class);

    $item->shouldReceive('createProcurement')
        ->once()
        ->with($group)
        ->andReturn($procurement);

    $result = $shipment->createProcurementForItem($item, $group);

    $this->assertSame($procurement, $result);
}

The ProcurementGroup class does not actually exist yet, however, in the first test I'm able to mock it and use it. Great.

Now, in the second test, I would expect to receive an error from the $group = app(ProcurementGroup::class); line since the class does not exist, but instead both test pass.

However, if I run only the second test by itself, then I do receive the error that the ProcurementGroup class does not exist.

So it seems that mocking the class in the first test is causing the second test to think the class actually exists. Is this expected behavior?

I was under the impression that since Laravel calls Mockery::close() in the tearDown method of its base test case, that all mock information should be destroyed in between each test.

What is going on here?

0 likes
4 replies
bobbybouwmann's avatar

I have no clue what's going wrong here. In general I would recommend you not to mock any of the models and just test against the database. This is a lot easier and provide you the same tests ;)

flyingL123's avatar

These models have nothing to do with a database. They aren't Eloquent models. I'm actually surprised you would make that statement not knowing anything about the domain or the codebase.

I appreciate your expertise (saw you speak at Laracon in NYC), and your contributions to Laravel, but going to have to disagree with you on this one.

bobbybouwmann's avatar

@flyingl123 I just assumed it were Eloquent models since this is a Laravel forum and most questions are about that! Also in your question you mentioned that the previous class was created before, which for me indicated that it was saved somewhere in the database. Apparently that is not what you're talking about.

Great that you were at the conference! Did you like it?

flyingL123's avatar

Yes, loved it. I was so glad I could make it. Very inspiring to see the Laravel community in-person. All the speakers were great (including yourself!). For me the highlight was actually Justin Jackson's talk which really had nothing to do with Laravel or programming. Was not expecting that.

Please or to participate in this conversation.