我正在尝试模拟没有任何虚函数的类。我读过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*也不起作用,因为该调用将是模棱两可的。

    使用虚函数实现模拟将很简单。没有,没有那么多。

    10-06 08:55