Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")
I'm interested to hear how people would go about this. I need to test a rate throttler for sending emails. As such the class needs to take time() snapshots and sleep() for durations of time based on averages.
I've tested this same thing before and just had my test sleep for anywhere up to 60 seconds which plain sucked
This time I've added a bit of bloat for the sake of testing (pseudo code shown):
As you've done, a mock is the usual way to go about doing things.
I have, however, discovered an interesting way to do this in PHP: using __call() you can create single global PHP function wrapper; instead of sleep() call $php->sleep(). You then have one mock you need to configure.
ole wrote:Just test for null-ness in the constructor and assign your default Sleeper and Timer classes to $this->_sleep and $this->_timer respectively.
That's how I would have done it previously but people run Swift for very long period of time sometimes and circular references cause all kinds of problems
<?php
class Sleeper {
public function sleep($seconds) {
sleep($seconds);
}
}
class Timer {
public function time() {
// whatever your default implementation is
}
}
class Whatever {
private $sleeper;
private $timer;
public function __construct($sleeper = null, $timer = null) {
if (!$timer) {
$timer = new Timer();
}
if (!$sleeper) {
$sleeper = new Sleeper();
}
$this->setTimer($timer);
$this->setSleeper($sleeper);
}
public function exampleOfSleeperUsage()
{
$this->sleeper->sleep(1);
}
}
Timer and Sleeper are interfaces My code is mocking them. It's much lighter than making them concrete dependencies IMO. I've avoided such tight coupling on every single line of code in v4 (everything is injected using DI).
I don't think there needs to be separate Timer and Sleeper classes except when testing so a mockable interface should really suffice. I'm open to debate though
I don't think there needs to be separate Timer and Sleeper classes except when testing so a mockable interface should really suffice. I'm open to debate though
You say that like what I propose is more complex but mine requires 2 classes and yours requires 2 interfaces. I think mine is more straight-forward and representative of the fact that you want to allow timing and sleeping to be flexible elements of the system (even if it is just for mocks).
The only reason you want to define interfaces is because you like to type hint things. To me what you are doing is adding a big restriction on yourself by type hinting and then having to work around the problems that brings instead of just removing the restriction. I save myself the effort, defining interfaces, by not type hinting.
It's much lighter than making them concrete dependencies IMO.
All I'm doing is shifting a tiny bit of behaviour from a method to a class and reducing some logic in the process. If it develops into a dependency you might want to stick a factory in the middle but I doubt that it will.