Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

373
Visualizações
PHP Unit Testing - Mock static autoloaded class with Mockery

I want to unit test a wrapper class for the official Segment PHP integration. Therefore I'll have to mock the Segment class with Mockery so there won't be any real API requests.

The Problem

The class to mock consists only of static methods. Because of this I try to mock it like this (with alias):

$segment = Mockery::mock('alias:Segment');

This works, but only if the class isn't autoloaded by composer. If I load it - like I have to for the rest of the app - I'll get the error

Could not load mock Segment, class already exists.

(That makes sense, because the docs state that an aliased class must not be loaded before.)

The question

How can I mock this (evil?) class, but still use it as usual in the rest of my app?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Essentially, you cannot mock classes with static calls.

Static calls always reference exactly the class and method to be called, which is equivalent to pointing to exactly the file and line of code to be executed (if you assume basic autoloading capability is available).

The only way to execute different code is to NOT having included the original class, but to load the mock class code first. It does not matter if you have an alternative code file, or if you are calling eval() by using Mockery. Both ways will work.

But they will also work only one time. You cannot switch back to the original code in a later test, because the class can only be defined once per script run. And not being able to switch implementations (like original vs. mocked vs. another mocked) is the problem here.

The solution, which also was mentioned in the comments: Don't have classes with static methods. Always create instances of classes and call dynamic methods. This way you can easily mock the class, but it requires to create an instance first, and offer a way to inject the class (or at least the mocked class) into the code you want to test.

As a generic pattern I am using this if dependency injection is not available in the project (I have to deal with some legacy stuff at times):

public function __construct(MyClass $class = null) {
    $this->class = $class ?: new MyClass();
}

This way I don't have to inject the class, but I would be able to inject a mock instead of the real class.

For situations where dependency injection is available, the constructor will be a very basic initializer:

public function __construct(MyClass $class) {
    $this->class = $class;
}

This works great if your dependency injection framework is able to do auto wiring (like PHP-DI), and you only have exactly one MyClass, because this will be automatically injected without you having to define anything.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda