#Unit Testing Code Mocking

16 messages · Page 1 of 1 (latest)

twin sinew
#

So I've been looking at unit testing the code at my company and the current unit testing framework relies heavy on virtual interfaces in order to be able to easily mock classes.

My issue with this is that this adds real world runtime overhead in our shipped code because of these interfaces. In essence we are only adding virtual methods for the pure purpose of ease of unit testing.

I think there could be a better way for us to be able to mock classes without needing virtual but I thought I would ask how others do it / recommend it from their experience.

Personally I was exploring the avenue of CRTP in order to help mock classes/interfaces but I'm not sure if this is over complicated. Does anyone have any advice?

cunning nymphBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

sinful pier
#

So you use interfaces so you can create both a mock and the real class.

#

CRTP
This is not really for CRTP but just regular templates.

#

Just have the mock class have the exact same static interface and have function templates.

#

You can probably also constraint the template parameters with a concept that is only satisfied for the actual class and the mock, or alternatively based on the static interface of the object.

#

Before

struct logger
{
    virtual void log(std::string_view s);
};

void do_something_with_logger(logger& logger);

After

template <typename T>
concept logger = requires(T& t, std::string_view s)
{
    { t.log(s); }
};

// or alternatively allow only specific types to avoid unnecessarily defining the functions.
template <typename T>
concept logger = std::same_as<T, actual_logger> || std::same_as<T, mock_logger>;

void do_something_with_logger(logger auto& logger);
twin sinew
sinful pier
#

Or well if that's not convenient just have unconstrained templates.

#

static_assert should be pretty easy to do.

#
template <typename T>
bool is_logger_v = std::is_same_v<T, actual_logger> || std::is_same_v<T, mock_logger>;

template <typename T>
void do_something_with_logger(T& t) { static_assert(is_logger_v<T>); ... }
#

Either this or SFINAE or you don't constraint anything but you will from bad error messages if you passed in a wrong object in that case.

twin sinew
#

Yeah I could static assert them. Thanks for some idea's, we do also use gmocks in places so maybe I should learn than and see what that can do for us

cunning nymphBOT
#

@twin sinew Has your question been resolved? If so, type !solved :)

twin sinew
#

!solved