Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying to return an object when mocking a parser class. This is the test code using PHPUnit 3.7

    //set up the result object that I want to be returned from the call to parse method
    $parserResult= new ParserResult();
    $parserResult->setSegment('some string');        

    //set up the stub Parser object
    $stubParser=$this->getMock('Parser');
    $stubParser->expects($this->any())
               ->method('parse')
               ->will($this->returnValue($parserResult));

    //injecting the stub to my client class
    $fileWriter= new FileWriter($stubParser);
    $output=$fileWriter->writeStringToFile();

Inside my writeStringToFile() method I'm using $parserResult like this:

writeStringToFile(){
   //Some code...
    $parserResult=$parser->parse();
    $segment=$parserResult->getSegment();//that's why I set the segment in the test.
}

Should I mock ParserResult in the first place, so that the mock returns a mock? Is it good design for mocks to return mocks?

Is there a better approach to do this all?!

share|improve this question

2 Answers 2

up vote 2 down vote accepted

In general having a chain of mocks returning other mocks is considered a code smell in tests.

That being said, the answer of whether this is good idea is of course "it depends".

About your ParserResult object - if it is a small value object then constructing it and passing it in is probably a good idea.

If it is a large object with dependancies of its own, then mocking it would be a better option. Not mocking it would increase the coupling in your tests.

Another question to ask about the design is what is the result of ParserResult.getSegment used for? Perhaps a Tell Don't Ask style might be better, can you tell ParserResult or Parser to do something with the segment information instead of extracting it and then operating on it?

share|improve this answer
    
well the thing is my FileWriter class which I inject the parser into will probably have about 4 other injected parsers into it. Each one of them will return a ParserResult object. Then $output will be constructed from the 5 ParserResult objects. –  Songo Oct 15 '12 at 7:56
    
Sounds like you might have a collection of Parsers which will give you a collection of ParserResults. Perhaps also another object which does the formatting of the output of those results which then your FileWriter would write to the file. If you go down that route then you'd only be mocking this ParserCollection object. But I feel I am speculating too much; my advice is to go the direction you are going in and pay attention to the pain points and code smells as you add more Parsers to the mix. –  verdammelt Oct 15 '12 at 11:25

I think it's a good idea to mock the smallest and closest possible set of dependencies to the class you are testing. The idea is to reduce the test into the simplest possible scenario so it's easy to ensure the test is correct and that only tests one thing.

If you return a mock you are testing two separate things, the function that consumes the mock and the class that now creates and returns the mock.

So test the consumer and the producer of the ParserResult separately.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.