Are mocks necessary?

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")

Moderator: General Moderators

josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Are mocks necessary?

Post by josh »

allspiritseve wrote:I thought I had read somewhere that you had rewritten a part of Simpletest to allow testing of objects with overloading methods... did I remember that correctly or am I making things up?

It'd be nice to hear your opinion on where we're headed in the Skeleton DataMapper thread.

Cory
I assume you mean for mocks, Yeah - I don't remember what was involved because halfway through I gave up, didn't seem worth my time. You basically would need to hack the library if you want to be able to be able to tell the mock interchangeably whether to expect __call vs expecting the explicit method signature. Hope this helps.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

jshpro2 wrote:I assume you mean for mocks, Yeah - I don't remember what was involved because halfway through I gave up, didn't seem worth my time. You basically would need to hack the library if you want to be able to be able to tell the mock interchangeably whether to expect __call vs expecting the explicit method signature. Hope this helps.
Well, not mocks, I want to test a class with some __call magic. I'm making a call to a method that doesn't exist, and Simpletest doesn't like that.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

Should be easy to fix that, I don't remember how but using a GUI based debugger makes it really easy to follow the stack and find elusive code. the hard hack is to make mocks work. I got it working in under an hour with overloading for TDD. ( and then spent several hours and then gave up on mocks )
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

I think this is the offender (in mock_objects.php):

Code: Select all

   function _bailOutIfNotMocked($alias) {
        $code  = "        if (! in_array(strtolower($alias), \$this->_mocked_methods)) {\n";
        $code .= "            trigger_error(\"Method [$alias] is not mocked\");\n";
        $code .= "            \$null = null;\n";
        $code .= "            return \$null;\n";
        $code .= "        }\n";
        return $code;
    }
 
Fixed like this:

Code: Select all

$code  = "        if (! in_array(strtolower($alias), \$this->_mocked_methods) && !in_array ('__call', \$this->_mocked_methods)) {\n";
(Oh, and the problem was a mock, not the class under test).
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

That was the easy part. I fell for the same trap, there's some other problem... I think telling the mock expect once __call and then calling the overriden signature, or visa versa.. that was the hard problem.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

jshpro2 wrote:That was the easy part. I fell for the same trap, there's some other problem... I think telling the mock expect once __call and then calling the overriden signature, or visa versa.. that was the hard problem.
Maybe you've tried this, but could you subclass the class you're trying to mock with the overridden method? It shouldn't matter what the class actually does, just the interface...

Code: Select all

class FakeClass extends Class   {
 
function thisMethodDoesntExist()    {
}
 
}
 
Mock::Generate ('FakeClass');
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

That was the problem.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

jshpro2 wrote:That was the problem.
I don't understand, why would that be a problem? If you're trying to mock a method on an existing class, but the class uses __call to overload that method, you need to be able to mock that method without actually adding the method. Subclassing would allow you to add a method solely for testing purposes. It seems to me that would solve your problem, not be your problem. If I've misunderstood, can you explain what your problem is?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

if I tell the mock to expect once '__call( 'implicitMethod' ) and then later replace with'' explicitMethod() ' I ran into problems with the architecture of simpletest.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

jshpro2 wrote:if I tell the mock to expect once '__call( 'implicitMethod' ) and then later replace with'' explicitMethod() ' I ran into problems with the architecture of simpletest.
What I'm saying is, don't tell it to expect __call. You're mocking the interface, not the implementation. Unless you're calling __call directly (why?) there's no reason to mock it. Only mock what the code under test is using, which in this case would be explicitMethod() (or implicitMethod(), I'm not sure why you have two).
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

So you tell the mock to expect __call and then later you want to hash out the explicit method to override it, and the tests go off?
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

allspiritseve wrote:What I'm saying is, don't tell it to expect __call.
jshpro2 wrote:So you tell the mock to expect __call
?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

That was the problem, I was able to make it so I could tell it to expect __call, but if I told it to expect explicitMethod() and then called the overloaded method ( __call ) it also choked. Maybe Im not remembering right but the problem was something along the lines. After I realized I didnt need mocks OR overloading though, I stopped caring honestly :lol:
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: DataMapper and TableDataGateway Design Concepts

Post by allspiritseve »

jshpro2 wrote:That was the problem, I was able to make it so I could tell it to expect __call, but if I told it to expect explicitMethod() and then called the overloaded method ( __call ) it also choked. Maybe Im not remembering right but the problem was something along the lines. After I realized I didnt need mocks OR overloading though, I stopped caring honestly :lol:
What I'm saying, is to tell it to expect the same method you're calling. (None of which would be __call). Overloading is an implementation detail, and shouldn't have any place in a mock object.

If you're doing TDD without mocks you are severely handicapping your testing capabilities.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: DataMapper and TableDataGateway Design Concepts

Post by josh »

allspiritseve wrote: Overloading is an implementation detail, and shouldn't have any place in a mock object.
"should", I'm just telling you the problem I personally ran into. Just because it should be designed one way doesn't mean simpletest choose to design it that way. I understand how it "should" work, all I was saying is I personally found it to be a pain to make it work that way.
allspiritseve wrote: If you're doing TDD without mocks you are severely handicapping your testing capabilities.
Flexibility comes inversely to control. If you don't program directly in machine code you're severely handicapping your programming capabilities too ;-)
Post Reply