Funny Experience...

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

User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

McGruff wrote:
I think I can rip out all the tally's and all the expectCallCounts as that's not really important here. I guess I really only needed stubs. If I do that, I think its less instrusive.
Interaction-based tests are by their nature intrusive but that's the point. You're trying to figure out the interfaces of neighbouring objects in the design, and how these will be used by the object under test.

Stubs just return values on demand but mocks also allow you to set expected call counts and the arguments expected at each method call. The expectations are important: without them, it wouldn't be TDD. With expectations, the test case verifies that the primary object interacts with the mock in a specific way. Stubs don't do this. There's no way to assert that a mock foo() method is being called with the correct number of arguments, or how many times it's called in total.
I think I'm balking at something close to the "Law/Suggestion of Demeter". Its one thing to use expectations/mocks to dictate how a given outside class interoperates with the test under discussion. Its something else to use the expectations/mocks to say how the class interoperates with the classes one more step away.

In this case. why should the handler test care if the handler's implementation invokes the getUserName method once (and caches it) or twice, etc. The test should test the the "interface" of the class not its detailed implementation, right? Doesn't testing the imeplementation as deep as mocks do promote a tigher coupling than might be desired?
McGruff
DevNet Master
Posts: 2893
Joined: Thu Jan 30, 2003 8:26 pm
Location: Glasgow, Scotland

Post by McGruff »

nielsene wrote:In this case. why should the handler test care if the handler's implementation invokes the getUserName method once (and caches it) or twice, etc. The test should test the the "interface" of the class not its detailed implementation, right? Doesn't testing the imeplementation as deep as mocks do promote a tigher coupling than might be desired?
The test case is certainly more tightly coupled to the implementation but I don't think it leads to too close a relationship between application objects. That's up to the programmer.

Only a small part of the implementation is exposed ie the mock object interface and the calls made to this. That's one of the main objects of the exercise if you're using testing as a design tool, as well as verifying that calls to the primary object's own interface create the expected effects.

Interaction-based tests are less useful for refactoring though - they'll have to keep pace with any changes. Later, I'd add state-based integration tests which provide a constant reference point against which to refactor.
Post Reply