Contain Your Environment Many modules must access elements of their environment that are too heavyweight for use in tests, for example, the file system or network. To keep tests lightweight, we mock out these elements. But what if no mockable interface is available, or the existing interfaces pull in extraneous dependencies? In such cases we can introduce a mediator interface that's directly associated with your module (usually as a public inner class). We call this mediator an "Env" (for environment); this name helps readers of your class recognize the purpose of this interface. For example, consider a class that cleans the file system underlying a storage system: // Deletes files that are no longer reachable via our storage system's metadata. class FileCleaner { public: class Env { public: // These methods return false or NULL on error. virtual bool MatchFiles(const char* pattern, vector* filenames) = 0; virtual bool BulkDelete(const vector& filenames) = 0; virtual MetadataReader* NewMetadataReader() = 0; // factory method virtual ~Env(); // don't forget the virtual destructor! }; // Constructs a FileCleaner. Uses “env” to access files and metadata. FileCleaner(Env* env, QuotaManager* qm); // non-Env args are fine, too! // Deletes files that are not reachable via metadata. Returns true on success. bool CleanOnce(); };
FileCleaner::Env lets us test FileCleaner without accessing the real file system or metadata. It also makes it easy to simulate various kinds of failures, for example, of the file system: class NoFileSystemEnv : public FileCleaner::Env { virtual bool MatchFiles(const char* pattern, vector* filenames) { match_files_called_ = true; return false; // failure } ... }; TEST(FileCleanerTest, FileCleaningFailsWhenFileSystemFails) { NoFileSystemEnv* env = new NoFileSystemEnv(); FileCleaner cleaner(env, new MockQuotaManager()); // takes ownership of “env” ASSERT_FALSE(cleaner.CleanOnce()); ASSERT_TRUE(env->match_files_called_); }
An Env object is particularly useful for restricting access to other modules or systems, for example, when those modules have overly-wide interfaces. This has the additional benefit of reducing your class's dependencies. However, be careful to keep the “real” Env implementation simple, lest you introduce hard-to-find bugs in the Env. The methods of your “real” Env implementation should just delegate to other, well-tested methods. The most important benefits of an Env are that it documents how your class accesses its environment and it encourages future modifications to your module to keep tests small by extending and mocking out the Env.
Oct 30, 2008 - Many modules must access elements of their environment that are too ... FileCleaner::Env lets us test FileCleaner without accessing the real file ...
In real- world case studies, we show that language-interface errors require single-environment debuggers to restart execution multiple times, whereas Blink directly diagnoses them with one execution. ... produce bugs found in real programs and compar
Mar 11, 2015 - the proper analytical tools to evaluate accountability initiatives:6 A major ... ing, this new term refers to an analytical framework that maps the ...
colony recognition. We used gas chromatography and mass spectrometry to investigate whether interaural gland secretions, sampled from wild female Bechstein's bats belonging to four colonies, contain information about the carrier. Based on our knowled
Nov 17, 2010 - variations in loudness of speech between different programs. 5'457'769 A ..... In an alternative implementation, the loudness esti mator 14 also ... receives an indication of loudness or signal energy for all segments and makes ...
Beyond Infinity: An expedition to the outer limits of the mathematical universe ... Utopians, Hackers, and the Futurists Solving the Modest Problem · of Death.
Nov 17, 2010 - the implementation described here, the block length for cal. 20. 25. 30. 35 ..... processing circuitry coupled to the input terminal and the memory ...