While @Mestkon is correct that it is not possible to arbitrarily populate std::filesystem:directory_entry
, I did find a way to wrap it in a way which incurs very little compile time overhead and zero runtime overhead:
class unmocked {};
template <typename T>
class mocked : unmocked {};
template <typename T>
using mockable = std::conditional_t<
std::is_base_of_v<unmocked, mocked<T>>,
T,
mocked<T>
>;
#ifdef UNIT_TEST
template <typename T>
class mocked<std::filesystem::directory_entry> {
// Match T constructors, functions, operators
};
#endif
In production, without any specialization, mockable<T> == T
, so performance is not impacted. In UT, we can provide simple backing fields for every getter, or forward them to a gmock object. Note that MOCK_METHOD
makes an object non-copyable, so you might need to store a reference or smart pointer to the mock, depending on your needs.