Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

271
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!