In my question As a “mockist” TDD practitioner, should I mock other methods in the same class as the method under test?, Avdi answered "Personally I think that mocking on self is almost always a code smell. It's testing the implementation rather than the behavior." He may be right, but often I can't distinguish between the implementation and the behavior.
I have another example (in Python-style pseudo-code) that may lead to helpful answers:
class Consumer:
def spec_dirpath:
client = VCS.get_connection(self.vcs_client_name)
client.sync()
return client.dirpath()
def spec_filepath:
filepath = os.path.join(spec_dirpath(), self.spec_filename)
if not os.path.exists(filepath):
raise ConsumerException
return filepath
def get_components:
return Components.get_components_from_spec_file(self.spec_filepath())
The idea here is that the get_components method calls the spec_filepath method in order to get a path to a file that the get_components_from_spec_file Components class method will read a list of components from. The spec_filepath method in turn calls spec_dirpath, which syncs the directory containing the spec file from the VCS system and returns the path to that directory. (Try not to look for bugs in this code--it's pseudo-code, after all.)
I'm looking for advice on how to test these methods...
Testing spec_dirpath should be quite straightforward. I can mock the VCS class and have it return a mock object and confirm the appropriate methods are called (and that the spec_dirpath method returns what the mock's dirpath method returns).
But if I don't mock spec_dirpath while testing spec_filepath, how do I avoid duplicating the same test code from the spec_dirpath code in the spec_filepath test? And if I don't mock spec_filepath while testing get_components, how do I avoid duplicating the test code from both spec_filepath and spec_dirpath?