(resuming our testing on the toilet posts...)
In a previous episode, we extracted methods to simplify testing in Python. But if these extracted methods make the most sense as private class members, how can you write your production code so it doesn't depend on your test code? In Python this is easy; but in C++, testing private members requires more friend contortions than a game of Twister®.
friend
// my_package/dashboard.hclass Dashboard { private: scoped_ptr<Database> database_; // instantiated in constructor // Declaration of functions GetResults(), GetResultsFromCache(), // GetResultsFromDatabase(), CountPassFail() friend class DashboardTest; // one friend declaration per test // fixture};
You can apply the Extract Class and Extract Interface refactorings to create a new helper class containing the implementation. Forward declare the new interface in the .h of the original class, and have the original class hold a pointer to the interface. (This is similar to the Pimpl idiom.) You can distinguish between the public API and the implementation details by separating the headers into different subdirectories (/my_package/public/ and /my_package/ in this example):
.h
/my_package/public/
/my_package/
// my_package/public/dashboard.hclass ResultsLog; // extracted helper interfaceclass Dashboard { public: explicit Dashboard(ResultsLog* results) : results_(results) { } private: scoped_ptr<ResultsLog> results_;};// my_package/results_log.hclass ResultsLog { public: // Declaration of functions GetResults(), // GetResultsFromCache(), // GetResultsFromDatabase(), CountPassFail()};// my_package/live_results_log.hclass LiveResultsLog : public ResultsLog { public: explicit LiveResultsLog(Database* database) : database_(database) { }};
Now you can test LiveResultsLog without resorting to friend declarations. This also enables you to inject MockResultsLog instance when testing the Dashboard class. The functionality is still private to the original class, and the use of a helper class results in smaller classes with better-defined responsibilities.
LiveResultsLog
MockResultsLog
Dashboard
Remember to download this episode of Testing on the Toilet and post it in your office.
Where is the download link ? I want to put this one in my office's toilets, along with the others
Glad to see ToT is back! :)
Yeah, glad to see ToT again, but as yvan said: where is the pdf version? I can't wait to put it in my office! :-D
why not just make them public? Then you would achieve the same ease of use as Python. And you would be beating "the man" ;)
I'm also wondering of PDF versions of pre-public-blog ToT episodes exist, and if those could be made public.
The comments you read and contribute here belong only to the person who posted them. We reserve the right to remove off-topic comments.
Where is the download link ? I want to put this one in my office's toilets, along with the others
ReplyDeleteGlad to see ToT is back! :)
ReplyDeleteYeah, glad to see ToT again, but as yvan said: where is the pdf version? I can't wait to put it in my office! :-D
ReplyDeletewhy not just make them public? Then you would achieve the same ease of use as Python. And you would be beating "the man" ;)
ReplyDeleteI'm also wondering of PDF versions of pre-public-blog ToT episodes exist, and if those could be made public.
ReplyDelete