Code Monkey home page Code Monkey logo

Comments (19)

svenluijten avatar svenluijten commented on May 9, 2024 8

After our discussion in Slack, Nuno found the issue:

The command is instantiated while bootstrapping everything (eg. building the application, etc.), so adding a mock into the container will not register with the command. To temporarily fix this, I've added the following method to my TestCase class to resolve the command out of the container again (with the right dependencies), and add it back to the application:

/**
 * @param string $command
 * @param array  $arguments
 */
protected function call($command, array $arguments = [])
{
    $command = $this->app->getContainer()->make($command);

    $this->app->add($command);

    $this->app->call($command->getName(), $arguments);
}

This way, we can do the following in the tests:

/** @test */
function it_tests_a_mocked_dependency()
{
    $mock = $this->createMock(TestService::class);

    $this->app->getContainer()->instance(TestService::class, $mock);

    $mock->expects($this->once())->method('someMethod')->willReturn('from the tests');

    $this->call(HelloCommand::class);
}

Thanks, @nunomaduro for the help!

from laravel-zero.

nunomaduro avatar nunomaduro commented on May 9, 2024 1

@sandervanhooft You want to make sure a command is called right?

from laravel-zero.

nunomaduro avatar nunomaduro commented on May 9, 2024 1

I let you think about this, just make sure you prototype something quick and let's think about the real implementation later 👍

from laravel-zero.

svenluijten avatar svenluijten commented on May 9, 2024

After a bit of debugging by @rickbolton and myself, we found this line, which we thought was the perpetrator. We thought changing that to Container::getInstance() instead of manually newing up the container (like it is now) would fix the issue, but it didn't.

Will do some more digging!

from laravel-zero.

jhoff avatar jhoff commented on May 9, 2024

Thanks for this. I just spent a day fighting with this issue.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

Is there a way to only bind and not call the mocked command? I am trying to test that executing command A (non-mocked) after completion calls command B (mocked).

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

Hi @nunomaduro , yes that's right.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

Meanwhile, I'm testing the solution offered by @svenluijten:

  1. I receive an error that the call() method should be made public instead of protected. So I did.
  2. Then I receive another error:
Call to undefined method LaravelZero\Framework\Application::getContainer()

This is triggered for this line from Sven's example:

$this->app->getContainer()->instance(PaymentListCommand::class, $mock);

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

The only non-basic thing is that I have Console Dusk installed.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

@sandervanhooft You want to make sure a command is called right?

Yes, but the command I want to make sure is called is called indirectly from another command.

from laravel-zero.

nunomaduro avatar nunomaduro commented on May 9, 2024

@sandervanhooft A solution may be have a class service that does the real job from the secondary command. And then, mock that service class using the container.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

I'm going to dive a bit deeper into this in the next few days (hopefully), will let you know how it goes!

So far absolutely 💗💗 Laravel Zero by the way!

And however briefly - nice to meet you at Laracon.eu!

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

@sandervanhooft A solution may be have a class service that does the real job from the secondary command. And then, mock that service class using the container.

May be an interesting approach, but I think the assertCommandCalled will be a recurring theme in my app and probably in other devs' as well.

from laravel-zero.

nunomaduro avatar nunomaduro commented on May 9, 2024

Hummmm. Could you think about an implementation for that? Would be good to add it to Laravel Zero or even to Laravel itself.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

Absolutely no idea yet. May need to implement a spy on the Kernel?

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

Did a quick scan, I can think of three directions currently:

  1. Inspired by Event::fake(), wrap Illuminate\Command in a spy when using Command:spy helper. Then use a assertCommandCalled($command, ?$callback) test helper for asserting. It seems impossible to me to go a level deeper because then we get into Symphony territory.

  2. Add lifecycle Events to the Command calls (like Eloquent model has) and track these using Event::fake() and Event::assertDispatched(...)

  3. Do both. But that's a bit much atm.

What do you think?

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

(1. "feels" possible, but will be a stretch for me so may take some time)

from laravel-zero.

nunomaduro avatar nunomaduro commented on May 9, 2024

@sandervanhooft Can you create a new issue with the content of that proposal? Sorry, but I would like to really follow this.

from laravel-zero.

sandervanhooft avatar sandervanhooft commented on May 9, 2024

@nunomaduro Done. See #178.

from laravel-zero.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.