2

I have an abstract class with some concrete and abstract protected methods, and I have a PHPUnit test for this abstract class.

Then I have classes that extend the abstract class and implement the abstract protected methods.

I'm curious of the smartest way to test that the child classes return what they need to return from the otherwise abstracted protected methods.

I have read a lot that you should not test private/protected methods, but I'm finding this awkward because to get code coverage across the protected method, I must replicate many of the tests from the abstract class test, which involves producing many mock objects and setting their methods to return specific values.

The end result will be a lot of tests that have very tight coupling to other classes. If I changes a class, the tests on for class need to change (totally ok), and then countless mock implementation of that class will need to change also.

At the end of the day, if the abstract class works, then I know my child object will work also, so long as it's implementation of the abstract protected methods returns an expected value.

So I'm wondering if I'm overlooking a pattern.

Duplicating tests across every child class doesn't seem to be better than testing that the child classes correctly implement their interfaces.

2
  • I have done what you are suggesting, and actually moved the tests into common code that can be included/required into my tests. I test the abstract classes for the same reasons you mentioned. I just did the same test extraction to not have to duplicate the code that does the tests. Simply REQUIRE() the PHP file with the tests, and then call them. Commented Nov 21, 2014 at 16:53
  • That's for suggestion. I never think to split out re-usable tests. I think this is probably the smartest way to go. Commented Nov 24, 2014 at 19:48

1 Answer 1

1

You are overlooking a pattern. It would be the Strategy Pattern. The protected methods of the child objects should be refactored into their own object with the protected method as a public method. You would then be able to test that these public methods return the correct thing.

Your tests for the base class would only need to change to have the mock object passed in. If your child classes are only implementing protected methods of the base abstract class. You can remove the abstract from the base class and have the children implement a strategy interface.

This will make your design more flexible. You would be able to easily extend the base class for other reasons and still have all of the previous functionality available to you.

Sign up to request clarification or add additional context in comments.

1 Comment

That is not what I was thinking of, but is exactly the correct answer. It's awkward to test because my design was poor. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.