I ran into this when I tried to write unit tests for a move-only class. I don't know how to write a test which checks if move operations actually moved the class's data members. I included here a simplified example of a class that parallels what I am working on. In reality that class supports a few more operations and (std::multimap
) data members which shouldn't be relevant here.
#include <vector>
class MyClass {
public:
inline MyClass() = default;
MyClass(const MyClass& other) = delete;
MyClass(MyClass&& other) = default;
MyClass& operator=(const MyClass& other) = delete;
MyClass& operator=(MyClass&& other) = default;
~MyClass() = default;
inline void set(const std::vector<MyStruct>& data) {data_ = data;}
inline const std::vector<MyStruct>& get() {return data_;}
private:
std::vector<MyStruct> data_;
};
MyStruct
contains only primitive data types (int
, float
and double
) and some std::string
types as (public
) data members. For completeness, I added a definition for MyStruct
at the end.
I am not sure how to even begin and couldn't find anything by searching online. Ideally, a googletest or googlemock solution would be great, but just a general approach or how it is done in other testing frame works might help me understand it and implement it in my preferred framework.
#include <string>
struct MyStruct {
int foo;
float bar;
double baz;
std::string fips;
};
Solutions so far (from comments and answers below):
Possible approach 1
Based on my exchange with @MutableSideEffect
Mock data members and test if their move operations are called when MyClass
's move operations are called.
This seems simple and straightforward. This indicates whether the (default
ed) move operations of MyClass
used the move operations of each of the data members. It should be the responsibility of the data members' types to provide proper move operations.
The only issue I have is that I don't know how to mock data types whose implementations I don't have access to without template-izing my entire code (as described in the google mock docs for mocking non-virtual functions).
In this particular case, though, I could still mock MyStruct
and test whether its move operations are called when MyClass
's move operations are called.
Possible approach 2
Based on the answer by @Eljay.
Add a data member, say Marker mark
, to every class I defined, or to every class for which I want to know whether or not their data members are moved when the class's move operations are called. Instruct the Marker
class to record in an internal state which of its constructors lead to its construction. Then test whether move operations of MyClass
lead to internal state of its data member mark
reflecting that it was moved.
I am not sure how fully this approach tests that all data members were moved and not only the mark
data member. Also, this reminds me a lot to just mocking the data members which goes back to approach 1.