How to mock some service when test console command. I have some console command, in this command I get some service and I want mock this service
console command
const APP_SATISFACTION_REPORT = 'app:satisfactionrepor';
protected function configure()
{
    $this
        ->setName(self::APP_SATISFACTION_REPORT)
        ->setDescription('Send Satisfaction Report');
}
/**
 * @param InputInterface  $input
 * @param OutputInterface $output
 */
protected function execute(InputInterface $input, OutputInterface $output)
{
    $container = $this->getContainer();
    $serviceCompanyRepo = $container->get('app.repository.orm.service_company_repository');
    $satisfactionReport = $container->get('app.services.satisfaction_report');
    /** @var ServiceCompany $serviceCompany */
    foreach ($serviceCompanyRepo->findAll() as $serviceCompany) {
        try {
            $satisfactionReport->sendReport($serviceCompany);
        } catch (\Exception $e) {
            $io->warning(sprintf(
                'Failed to send satisfaction report for service company with ID %s',
                $serviceCompany->getId()
            ));
        }
    }
}
and my tests
 /** @var  Console\Application $application */
protected $application;
protected $container;
/** @var BufferedOutput $output */
protected $output;
/**
 * @var ServiceCompanyRepository
 */
private $serviceCompanyRepository;
prepare console command
public function setUp()
{
    parent::setUp();
    $entityManager = $this->getEntityManager();
    $this->serviceCompanyRepository = $entityManager->getRepository(ServiceCompany::class);
    static::bootKernel();
    $this->container = static::$kernel->getContainer();
    $this->application = new Console\Application(static::$kernel);
    $this->application->setAutoExit(false);
    $master = new SatisfactionReportCommand();
    $this->application->add($master);
}
public function setUpMaster() {
    $this->output = new BufferedOutput();
    $this->application->run(new ArgvInput([
        './bin/console',
        SatisfactionReportCommand::APP_SATISFACTION_REPORT,
    ]), $this->output);
} 
public function testGetMasterOutput()
{
    $this->loadFixture(ServiceCompany::class);
    /** @var ServiceCompany[] $serviceCompanies */
    $serviceCompanies = $this->serviceCompanyRepository->findAll();
    $this->assertCount(2, $serviceCompanies);
    $client = self::createClient();
mock service app.services.satisfaction_report
    $service = $this->getMockService($serviceCompanies);
and set it in container
    $client->getContainer()->set('app.services.satisfaction_report', $service);
    $this->setUpMaster();
    $output = $this->output->fetch();
}
protected function getMockService($serviceCompanies)
{
    $service = $this->getMockBuilder(SatisfactionReport::class)
        ->setMethods(['sendReport'])
        ->disableOriginalConstructor()
        ->getMock();
    $service
        ->expects($this->exactly(2))
        ->method('sendReport')
        ->withConsecutive(
            [$serviceCompanies[0]],
            [$serviceCompanies[1]]
        );
    return $service;
}
How to mock app.services.satisfaction_report? Set in container app.services.satisfaction_report not help me  
I had same problem but I resolved it.
I have base class:
class TestCase extends WebTestCase
{
    /** @var Application */
    private $application;
    private $mailServiceMock;
    protected function setMailService(MailService $mailServiceMock): void
    {
        $this->mailServiceMock = $mailServiceMock;
    }
    protected function getApplication(): Application
    {
        static::bootKernel();
        static::$kernel->getContainer()->get('test.client');
        $this->setMocks();
        $this->application = new Application(static::$kernel);
        $this->application->setCatchExceptions(false);
        $this->application->setAutoExit(false);
        return $this->application;
    }
    protected function execute(string $action, array $arguments = [], array $inputs = []): CommandTester
    {
        $tester = (new CommandTester($this->getApplication()->find($action)))->setInputs($inputs);
        $tester->execute($arguments);
        return $tester;
    }
    private function setMocks(): void
    {
        if ($this->mailServiceMock) {
            static::$kernel->getContainer()->set('mail', $this->mailServiceMock);
        }
    }
}
And test class
class SendEmailCommandTest extends TestCase
{
    public function testExecuteSendingError(): void
    {
        $mailServiceMock = $this->getMockBuilder(MailService::class)->disableOriginalConstructor()
        ->setMethods(['sendEmail'])->getMock();
        $mailServiceMock->method('sendEmail')->willThrowException(new \Exception());
        $this->setMailService($mailServiceMock);
        $tester = $this->execute(SendEmailCommand::COMMAND_NAME, self::NORMAL_PAYLOAD);
        $this->assertEquals(SendEmailCommand::STATUS_CODE_EMAIL_SENDING_ERROR, $tester->getStatusCode());
    }
}
As you can see I set mail service right after booting kernel.
And here you can see my services.yaml:
services:
  mail.command.send.email:
    autowire: true
    class: App\Command\SendEmailCommand
    arguments: ["@logger", "@mail"]
    tags:
      - {name: console.command, command: "mail:send.email"}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With