使用谷歌模拟C代码

Ale*_*lex 17 c c++ gcc unit-testing

我正在维护一个用C语言编写的遗留项目,并且使用C++编译器运行它是不可行的.由于代码是交叉编译的,因此可以在主机环境中运行单元测试或类似操作.因此,它也可以与C++主机编译器连接,并使用google-test和google-mock.

谷歌模拟的某些功能似乎非常诱人,可用于测试,如调用实际实现和设置调用期望.

我希望能够在C代码中使用它们.我可以看到,确实可以在不使用vtable的情况下使用google-mock,但它需要模板.

有没有办法用google mock模拟裸C函数?

Ale*_*lex 13

我发现了一种能够在google-mock中模拟裸C函数的方法.

解决方案是声明foobar是映射到的弱别名foobarImpl.在生产代码中,您没有实现foobar(),对于单元测试,您提供了一个调用静态模拟对象的实现.

此解决方案是GCC特定的,但还有其他编译器/链接器提供弱混叠.

  • 将函数重命名void foobar();void foobarImpl();
  • 为函数添加一个属性,foobar如:void foobar() __attribute__((weak, alias("foobarImpl") ));
  • 如果你想要一个非弱别名,请使用preproessor指令从属性中删除弱.

因此:

#pragma once
void foobar();
Run Code Online (Sandbox Code Playgroud)

// header.h
#pragma once

void foobar();    
void foobarImpl(); // real implementation
Run Code Online (Sandbox Code Playgroud)

extern "C" {
#include "header.h"
}
// code.c
void foobarImpl() {
  /* do sth */
}
void foobar() __attribute__(( weak, alias ("foobarImpl") )); // declare foobar to be a weak alias of foobarImpl
Run Code Online (Sandbox Code Playgroud)

这将告诉GNU链接链接的电话foobar()foobarImpl()时也没有所谓的符号foobar()

然后添加测试代码

struct FooInterface {
   virtual ~FooInterface() {}
   virtual void invokeFoo() const { }
};

class MockFoo : public FooInterface {
public:
  MOCK_CONST_METHOD0(invokeFoo, void());
}

struct RealFoo : public FooInterface {
   virtual ~RealFoo() {}
   virtual void invokeFoo() const { foobarImpl(); }
};

MockFoo mockFoo;
RealFoo realFoo;
void foobar() {
  mockFoo.invokeFoo();
}
Run Code Online (Sandbox Code Playgroud)

如果编译和链接此代码,它将替换foobar为模拟调用.如果你真的想打电话,foobar()你仍然可以添加默认调用.

ON_CALL(mockFoo, invokeFoo())
       .WillByDefault(Invoke(&realFoo,&RealFoo::invokeFoo));
Run Code Online (Sandbox Code Playgroud)

  • 很高兴看到您找到了一种可行的方法来包装C API函数.这种解决方案/解决方案是,我曾经想到的...... (2认同)