Writing unit tests for methods with a degree of randomization

I am using PHPUnit and my traditional approach is to use mock objects and methods called by the methods I am testing. The mocks tell you what to expect from the unit test input. The problem is that some of the input provided to mock objects is randomly generated by the methods being tested (and the unit test doesn't know what it is).

Just wondering if anyone can suggest a solution.

+2


source to share


5 answers


Can the "random part" be injected into a method (or is it a kernel function )

eg. (perhaps a simplified example taking "random" literally) instead of

function foo($x, $y) {
  return $x * rand(1, $y);
}

      



use something like

function foo($x, $r) {
  return $x * $r->getNext();
}

      

This way you eliminate as much "randomness" as possible in your tests, since you can pass an object for $ r that doesn't actually return random values, but edge cases, for example.

+2


source


It's hard to tell without knowing your specific case, but perhaps you could refactor to introduce some kind of random number provider into the object under test. During the test, you can use a solid number of random numbers to get reproducible results.



+2


source


If you have a map of expected results, and you draw randomly from a set of keys, you may have a degree of randomness and still be able to predict what the expected result is.

+2


source


I always think of a unit test as being repeatable . (I mean, each run behaves the same and gives the same result).
There are other prerequisites for a unit test, but for me this is the most important one. (See this very good definition )

Given that, it would be impossible to test a specific case.
I would try to split the random thing of your code into a specific piece. Then I would think of it as a data source and so I would try to mock it.

Hope you can apply this to your context.

+1


source


You don't need to use mocks that are strict on their inputs - just do so when it adds value to your tests.

In other scenarios, use stubs that don't care about typing them, or some methods must be strict and, if necessary, free.

0


source







All Articles