[ Content | View menu ]

PHPUnit getMock Method Signature

Mark Mzyk June 16, 2011

In writing unit tests for PHP, I normally use PHPUnit. I frequently use mocks, but forget the params for the getMock call after the first two arguments, as I don’t use the rest frequently. Looking up the method signature through Google is frustratingly difficult, so here it is for future reference.

PHPUnit getMock takes a possible seven params.

They are, in order:

  1. String – Required – the class name to mock
  2. Array – Optional – the methods to mock
  3. Array – Optional – arguments to pass to the mock’s constructor
  4. String – Optional – a class name for the mock
  5. Boolean – Optional – disable the call to the original class’ constructor
  6. Boolean – Optional – disable the call to the original object’s clone method
  7. Boolean – Optional – disable autoload during the mock object creation

The getMock implementation can be found on github, in the phpunit-mock-objects repo, in Generator.php.

Documentation on what I just explained can be found in the PHP 3.4 docs with arduous searching (see Table 22.6 TestCase), but I’ve not found the same page in the 3.5 docs.

I’ve never used beyond the third argument to getMock, so I have no idea how useful the rest are.

Programming - 0 Comments


Broken Windows

Mark Mzyk May 16, 2011

Companies are always touting the next big thing. Their newest product revolutionizes the industry. It can’t be lived without.

Advertising in this way reveals how most companies function: always attempting to create something new. Companies want to continually build new products and add new features, even if these come at the expense of fixing or improving existing functionality.

Prioritizing in this way is akin to having a house with a broken window, but instead of fixing the broken window you build a new addition onto the house. While the addition adds tremendous value, it will always be brought down in value as long as the window remains broken. As soon as the window is fixed, the house and addition rise in value1.

Consider this: how many broken windows are there where you work2?

A step further: what can you do to repair them?


Broken Window / CC License

  1. Broken Window Theory []
  2. Pragmatic Programmers: Software Entropy []

General - 0 Comments


Randomly Failing PHP Tests

Mark Mzyk April 20, 2011

At work we have several PHPUnit tests that randomly fail. These ghost failures cause a lot of pain. One run the test fails, the next it passes. These tests are slow poison, as they degrade trust in the system. The code was inspected, but nothing could be found wrong. For some reason, on random test runs, the arrays being returned would have their elements in a different order, but no one knew why.

The order of the arrays clearly mattered in our tests, so what was causing them to change that we didn’t expect?

Short version:

In the tests we were using PHPUnit’s assert functionality to test that two arrays were equal. If the ordering between the two arrays is off, even if they contain the same key value pairs, PHPUnit will fail the test. Comparing arrays in this way normally works, because PHP usually guarantees array order; however, under some circumstances order is not guaranteed. This was the cause of the random failures. To fix this, we just need to be smarter about how we compare arrays.

Long version:

In investigating one of the tests that was failing randomly, I saw that it was performing an assertEquals on two arrays. Sometimes this assert would fail because the ordering in one of the arrays had changed for that test run.

The question that is relevant here is this: does PHP guarantee the order of arrays?

The answer: it depends.

PHP arrays are implemented under the hood as an ordered map – what is essentially a Linked Hash Map in Java. Insertion order is guaranteed. However, PHP breaks this contract for some array functions, such as array_slice, which does not guarantee order unless a flag is set.

In the case of the test I investigated, the final array was being generated by an array_slice that was buried in the code. One potential fix is to change the code under test so it does not use array_slice or so the flag to maintain order is set. The other fix is to make the tests smarter.

I opted to go with option two, making the tests smarter. This can be done by using compare functions such as array_diff or array_diff_assoc and then asserting on the output of the compare function instead of asserting for equality between two arrays. Another option is to sort the output array, so it always has the same order. Your creativity is the limit on how you solve this.

What does this episode indicate? That it is worth understanding how the language you’re using operates. While PHP has more warts than most, all languages have idiosyncratic behavior that it is worth being aware of. The next time you see perplexing behavior, ask yourself why it’s happening and investigate. The reasoning why the language is behaving as it is might surprise you.

Programming - 0 Comments