我如何在 C 中使用谷歌模拟? [英] How do I use google mock in C?

查看:27
本文介绍了我如何在 C 中使用谷歌模拟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm maintaining a legacy project written in C and it's unfeasible to get it running with a C++ compiler. Since the code is cross compiled it is however possible to run unit-tests or similar in a host environment. hence it's also possible to interface with a C++ host compiler and use google-test and google-mock.

google-mock 的某些功能似乎非常适合用于测试,例如调用实际实现和设置调用预期.

There are certain capabilities of google-mock which seem to be very tempting to be used for testing as invoking real implementations and setting call expectations.

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

I would like to be able to use them in C code. I can see that it is indeed possible to use google-mock without using vtables, but it requires templates.

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

Is there a way to mock bare C functions with google mock?

编辑:

我基本上不得不使用 google mock,不过我认为其他所有阅读这篇文章的人都比我有更好的灵活性.

I basically had to use google mock, I assume though that everybody else who will read this thread has better flexibility than me.

推荐答案

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

I found a way to be able to mock bare C functions in google-mock.

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

The solution is to declare foobar to be a weak alias that maps to foobarImpl. In production code you do not implement foobar() and for unit tests you provide an implementation that calls a static mock object.

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

This solution is GCC specific but there are other compilers/linkers that provide weak aliasing.

  • 将函数void foobar();重命名为void foobarImpl();
  • 为函数 foobar 添加一个属性,例如:void foobar() __attribute__((weak, alias("foobarImpl") ));
  • 如果您想要一个非弱别名,请使用预处理器指令从属性中删除弱别名.
  • rename the function void foobar(); to void foobarImpl();
  • add an attribute to the function foobar like: void foobar() __attribute__((weak, alias("foobarImpl") ));
  • if you want to have a non weak alias use a preproessor directive to remove the weak from the attributes.

因此:

#pragma once
void foobar();

变成

// header.h
#pragma once

void foobar();    
void foobarImpl(); // real implementation

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

这将告诉 gnu 链接器在没有名为 foobar() 的符号时将 foobar() 的调用与 foobarImpl() 链接起来

This will tell the gnu linker to link calls of foobar() with foobarImpl() whenever there is no symbol called 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();
}

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

if this code is compiled and linked it will replace foobar with the mock call. if you really want to call foobar() you can still do add a default invocation.

ON_CALL(mockFoo, invokeFoo())
       .WillByDefault(Invoke(&realFoo,&RealFoo::invokeFoo));

这篇关于我如何在 C 中使用谷歌模拟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆