jshpro2 wrote:Feel free to show me up though, you seem to be more motivated then me, if you do it I'd love to have the code shared with me
Proof of concept, if you will...
Code: Select all
include ('MyClass.php');
class ExplicitInterface extends OverloadedClass {
function nonExistentMethod() {
}
}
Mock::Generate ('ExplicitInterface', 'MockOverloadedClass');
class TestMyClass extends UnitTestCase {
function __construct() {
$this->UnitTestCase();
}
function setUp() {
$this->mock = new MockOverloadedClass();
$this->class = new MyClass ($this->mock);
}
function testNonExistentMethod() {
$this->mock->expectOnce ('nonExistentMethod', array ('1'));
$this->class->poke();
}
}
jshpro2 wrote:I doubt I'll need overloading....with overloading you have no explicit interface.
Agreed, I've found my code gets a lot more explicit when I steer away from overloading. There are situations where it comes in handy though, like the lazy loading code I mentioned earlier.
jshpro2 wrote:IMO mocking is just 1 step closer to reading in the source file and actually asserting the contents of the class itself, instead of doing what TDD is supposed to do which is test the black box, outward facing API / functionality. Maybe you can convince me otherwise, what can I do with a mock I can't do with a stub? With mocks I can make sure my setters get called, with stubs you can test that same behavior by calling the setter(s) and then asserting the getters return the correct values.
My understanding of a
stub is a class that doesn't actually do anything. You just mock it and set return values. A mock, on the other hand, can set expectations for what is passed to it. You sound like you're using a fleshed-out class that actually has behavior (ie neither a mock or a stub).
If the classes the class under test uses are implemented, then you're testing both classes at once. How do you know, if the class under test returns the wrong value, whether the fault lies in the class under test or the supporting class? However, if you mocked that supporting class, told it to expect certain methods to be called, and to return certain values, then you are in control of that class. If everything but the class under test is controlled, you know that the only source for error is the class under test.
Additionally, with TDD, you can mock out classes you haven't built yet. Not only does this allow you to test a class that you otherwise couldn't, because it has too many dependencies, but you are also giving that mock object an interface that can be later used for when you're testing THAT class later on down the road. Hence why all the TDD documentation talks about the design of your application flowing out from that first test. Mocking helps you design your application just as much as it helps you test it.
I'm stepping off my soapbox now.
If you'd like to discuss this further, maybe we should start a thread in the TDD forums and not pollute this thread any longer?