Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

278
Vistas
PHPUnit: Getting equalTo assertion to ignore property

I have the following PHPUnit testcase:

    $mailer = $this->getMockBuilder(MailerInterface::class)->getMock();
    $simpleMailer = new SimpleMailer($mailer);

    $message = (new Message())
        ->setTo($user)
        ->setFrom($from)
        ->setSubject($subject)
        ->setTemplate(SimpleMailer::TEMPLATE)
        ->setContext(['message' => $body]);

    if ($bcc) { $message->addBcc($bcc); }

    $mailer
        ->expects($this->once())
        ->method('send')
        ->with($this->equalTo($message));

    $simpleMailer->sendMessage($user, $subject, $body, $from, $bcc);

This was working fine until the Message class was changed. The Message class now sets a unique ID on construction, meaning that equalTo now returns false with the following difference:

 MailerBundle\Document\Message Object (
-    'id' => '5a372f3c-a8a9-4e1e-913f-d756244c8e52'
+    'id' => '11176427-7d74-4a3c-8708-0026ae666f8b'
     'type' => null
     'user' => Tests\TestUser Object (...)
     'toName' => ''
     'toAddress' => null
     'domain' => null
     'fromName' => null
     'fromAddress' => 'user@example.org'
     'bccAddresses' => Array (...)
     'subject' => 'subject'
     'textBody' => null
     'htmlBody' => null
     'template' => 'MailerBundle:MailTemplates:...l.twig'
     'context' => Array (...)
)

Is there any way that I can exclude certain properties from the equality check?

about 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

If your Message class has getters, you can use a callback in with function to match only properties you care about. Something similar to

$mailer
    ->expects($this->once())
    ->method('send')
    ->with($this->callback(function(Message $message) use ($user, $from, $subject, $body) {
            return $message->getTo() == $user 
                && $message->getFrom() == $from 
                && $message->getSubject() == $subject 
                && $message->getTemplate() == SimpleMailer::TEMPLATE
                && $message->getContext()['message'] == $body
        }));
about 4 years ago · Santiago Trujillo Denunciar

0

I just wrote something similar, and was curious if I just reinvented the wheel (I pretty much did). However, I thought would share my result here in case it helps anyone, since it matches your use case like mine.

My goal was to compare two objects and assert equality between properties, with the ability to ignore specified keys. I'm using this with the current PHPunit (Feb 2020).

private function assertEqualWithIgnore($expected, $actual, $ignoreKeys = [], $currentKey = null): void
    {
        if (is_object($expected)) {
            foreach ($expected as $key => $value) {
                $this->assertEqualWithIgnore($expected->$key, $actual->$key, $ignoreKeys, $key);
            }
        } elseif (is_array($expected)) {
            foreach ($expected as $key => $value) {
                $this->assertEqualWithIgnore($expected[$key], $actual[$key], $ignoreKeys, $key);
            }
        } elseif ($currentKey !== null && !in_array($currentKey, $ignoreKeys)) {
            $this->assertEquals($expected, $actual);
        }
    }
about 4 years ago · Santiago Trujillo Denunciar

0

Inspired by Brian's answer, here is an helper that trim the unwanted ids before making an equality check. This way the behavior remains very close to phpunit's assertEquals.

You get the equality checks on all properties at once instead of one at the time. You can also more easily spot where the check is failing.

private function assertEqualsButIgnore($expected, $actual, $ignoreKeys = []): void
{
    $copyExpected = $expected;
    $this->recursiveUnset($copyExpected, $ignoreKeys);

    $copyActual = $actual;
    $this->recursiveUnset($copyActual, $ignoreKeys);

    $this->assertEquals($copyExpected, $copyActual);
}

private function recursiveUnset(&$objOrArray, $unwanted_key): void
{
    foreach($unwanted_key as $key) {
        if(is_array($objOrArray)) {
            unset($objOrArray[$key]);
        } else {
            unset($objOrArray->$key);
        }
    }
    foreach ($objOrArray as &$value) {
        if (is_array($value) || is_object(($value))) {
            $this->recursiveUnset($value, $unwanted_key);
        }
    }
}
about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda