我正在尝试模拟没有任何虚函数的类。我读过Curiously_recurring_template_pattern(CRTP)可以帮助实现这一目标。
这是代码。我正在尝试对功能getMyClassValue
进行单元测试
// file myclass.h
template<typename T>
struct MyClass_t {
int hello() {
return (static_cast<T*>(this))->hello_impl();
}
};
/*
Earlier MyClassImpl was just simple class like
struct MyClassImpl {
int hello() {
return 110;
}
};
// I changed it to below for making it mockable. Using CRTP.
*/
struct MyClassImpl : public MyClass_t<MyClassImpl> {
int hello_impl() {
return 110;
}
};
typedef MyClassImpl *MyClass;
int getMyClassValue(MyClass doc) {
return doc->hello();
}
// file main.cpp
#include <iostream>
/*
int main() {
MyClass myclass = new MyClassImpl();
std::cout << getMyClassValue(myclass);
delete myclass;
return 0;
}
*/
// file test.cpp
struct MyClassImplTest : public MyClass_t<MyClassImplTest>,
public virtual MyClassImpl {
int hello_impl() {
return 2;
}
};
int main() {
auto myclass = new MyClassImplTest();
std::cout << getMyClassValue(myclass);
delete myclass;
return 0;
}
我在控制台中收到
110
,而不是2
。为什么会这样呢?由于我使用的是指针,因此不应进行 slice 。
我如何实现 mock ?
最佳答案
确实,这与 slice 无关。实际上,发生的事情非常简单:
getMyClassValue
接受MyClassImpl*
类型的指针并调用hello
hello
的父代中的MyClassImpl
,即MyClass_t<MyClassImpl>
hello
静态将指针转换为T*
的MyClassImpl*
并调用hello_impl
MyClassImpl::hello_impl
返回110 对
hello
的调用无法解析为MyClass_t<MyClassImplTest>
的MyClassImplTest
父级,因为它是在MyClassImpl*
类型的指针上而不是在MyClassImplTest
类型的指针上调用的。除非您指定要使用的父级,否则尝试在hello
上调用MyClassImplTest*
也不起作用,因为该调用将是模棱两可的。使用虚函数实现模拟将很简单。没有,没有那么多。