gtest和gmock是针对c/c++的单元测试框架。
嵌入式中大多采用C语言进行开发,为了使用gmock对C语言项目进行单元测试,存在一些而外的工作需要做。
一、环境搭建
1.安装mingw
https://osdn.net/projects/mingw/releases/
添加E:\MinGW\mingw64\bin 到系统环境变量中
2.下载gtest gmock源码
https://github.com/google/googletest
二、编译gmock
1.拷贝E:\MinGW\mingw64\bin\mingw32-make.exe 到 E:\googletest-master\googlemock\make\mingw32-make.exe
2.执行E:\googletest-master\googlemock\make\mingw32-make.exe 在这里插入图片描述
运行结果将生成gmock_test.exe
在这里插入图片描述
运行gmock_test.exe
在这里插入图片描述
至此,gmock编译完成
三、适配到C语言项目中使用
1、在C语言项目中使用gtest

2、在C语言项目中使用gmock
定义mock 类
描述mock类中的方法
实例化mock类得到实例
使用函数包装mock类中的方法
使用mock函数进行单元测试

在googletest目录下新建一个test_c_code目录 在这里插入图片描述
新建两个C语言文件和一个C++测试文件:
在这里插入图片描述
code_in_c.h

#ifndef __CODE_IN_C_H__
#define __CODE_IN_C_H__
typedef struct c_struct_t{
    char *p_c_pointer;
    int(*p_c_func)(struct c_struct_t*);
}c_struct_t;
int c_func_caller(c_struct_t* p_c_struct);
#endif

code_in_c.c

#include "code_in_c.h"
#include <stdio.h>
int c_func(c_struct_t *p_c_struct)
    printf("%s", p_c_struct->p_c_pointer);
    return 0;
int c_func_caller(c_struct_t* p_c_struct)
    char words[40] = "hello, gmock test c code";
    char *p_words = words;
    int ret;
    p_c_struct->p_c_pointer = p_words;
    ret = p_c_struct->p_c_func(p_c_struct);
    return ret;
void main(void)
    c_struct_t c_struct;
    c_struct.p_c_func = c_func;
    c_func_caller(&c_struct);

gmock_test_c_code.cc

#include <gtest/gtest.h>
#include <gmock/gmock.h>
//引用被测函数的头文件
extern "C"
#include "code_in_c.h"
using namespace testing;
/*构造mock*/
//定义mock类
class Mock_FOO {
public:
    //定义mock方法
    MOCK_METHOD1(set, int(int num));
    //定义mock方法
    MOCK_METHOD0(get, int());
    //定义mock方法
    MOCK_METHOD1(mock_c_func, int(c_struct_t *p_c_struct));
//实例化mock对象
Mock_FOO mocker;
//创建mock对象方法的函数的C包装
int mock_c_func(c_struct_t *p_c_struct) {
    return mocker.mock_c_func(p_c_struct);
//测试被测函数
TEST(Atest, test_c_func_000)
    EXPECT_CALL(mocker, mock_c_func(IsNull())).WillRepeatedly(Return(654));
    c_struct_t c_struct_foo;
    c_struct_foo.p_c_func = mock_c_func;
    int ret = c_func_caller(&c_struct_foo);
    EXPECT_EQ(456, ret);
//测试被测函数
TEST(Atest, test_c_func_001)
    EXPECT_CALL(mocker, mock_c_func(An<c_struct_t *>())).WillRepeatedly(Return(654));
    c_struct_t c_struct_foo;
    c_struct_foo.p_c_func = mock_c_func;
    int l = c_func_caller(&c_struct_foo);
    EXPECT_EQ(654, l);
int main(int argc, char *argv[]) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();

修改E:\googletest-master\googlemock\make\Makefile,使得编译系统能够编译我们刚才添加的三个文件。
Makefile

# A sample Makefile for building both Google Mock and Google Test and
# using them in user tests.  This file is self-contained, so you don't
# need to use the Makefile in Google Test's source tree.  Please tweak
# it to suit your environment and project.  You may want to move it to
# your project's root directory.
# SYNOPSIS:
#   make [all]  - makes everything.
#   make TARGET - makes the given target.
#   make clean  - removes all files generated by make.
# Please tweak the following variable definitions as needed by your
# project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use
# in your own targets but shouldn't modify.
# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file, or if you want to use
# a copy of Google Test at a different location.
GTEST_DIR = ../../googletest
# Points to the location of the Google Test libraries
GTEST_LIB_DIR = .
# Points to the root of Google Mock, relative to where this file is.
# Remember to tweak this if you move this file.
GMOCK_DIR = ..
# Where to find user code.
# USER_DIR = ../test
USER_DIR = ../test_c_code
# Flags passed to the preprocessor.
# Set Google Test and Google Mock's header directories as system
# directories, such that the compiler doesn't generate warnings in
# these headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11
# Google Test libraries
GTEST_LIBS = libgtest.a libgtest_main.a libgmock.a libgmock_main.a
# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
# TESTS = gmock_test
TESTS = gmock_test_c_code
# All Google Test headers.  Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
                $(GTEST_DIR)/include/gtest/internal/*.h
# All Google Mock headers. Note that all Google Test headers are
# included here too, as they are #included by Google Mock headers.
# Usually you shouldn't change this definition.
GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
                $(GMOCK_DIR)/include/gmock/internal/*.h \
                $(GTEST_HEADERS)
# House-keeping build targets.
all : $(GTEST_LIBS) $(TESTS)
clean :
	rm -f $(GTEST_LIBS) $(TESTS) *.o
# Builds gmock.a and gmock_main.a.  These libraries contain both
# Google Mock and Google Test.  A test should link with either gmock.a
# or gmock_main.a, depending on whether it defines its own main()
# function.  It's fine if your test only uses features from Google
# Test (and not Google Mock).
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
# For simplicity and to avoid depending on implementation details of
# Google Mock and Google Test, the dependencies specified below are
# conservative and not optimized.  This is fine as Google Mock and
# Google Test compile fast and for ordinary users their source rarely
# changes.
gtest-all.o : $(GTEST_SRCS_)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
            -c $(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
            -c $(GTEST_DIR)/src/gtest_main.cc
gmock-all.o : $(GMOCK_SRCS_)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
            -c $(GMOCK_DIR)/src/gmock-all.cc
gmock_main.o : $(GMOCK_SRCS_)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
            -c $(GMOCK_DIR)/src/gmock_main.cc
libgtest.a : gtest-all.o
	$(AR) $(ARFLAGS) $@ $^
libgtest_main.a : gtest_main.o
	$(AR) $(ARFLAGS) $@ $^
libgmock.a : gmock-all.o
	$(AR) $(ARFLAGS) $@ $^
libgmock_main.a : gmock_main.o
	$(AR) $(ARFLAGS) $@ $^
# Builds a sample test.
gmock_test.o : $(USER_DIR)/gmock_test.cc $(GMOCK_HEADERS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test.cc
gmock_test : gmock_test.o $(GTEST_LIBS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -L$(GTEST_LIB_DIR) -lgmock -lpthread $^ -o $@
# Builds a sample test for c code.
code_in_c.o : $(USER_DIR)/code_in_c.c $(GMOCK_HEADERS)
	gcc $(CPPFLAGS) -c $(USER_DIR)/code_in_c.c
gmock_test_c_code.o : $(USER_DIR)/gmock_test_c_code.cc $(GMOCK_HEADERS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/gmock_test_c_code.cc
gmock_test_c_code : code_in_c.o gmock_test_c_code.o $(GTEST_LIBS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -L$(GTEST_LIB_DIR) -lgmock -lpthread $^ -o $@

最终,生成的我们的可执行测试文件:在这里插入图片描述
执行该测试文件:
在这里插入图片描述

本想免费的,但是现在改版,选项里最低必须是2分,sorry了。 相关博客地址: http://blog.csdn.net/songqier/article/details/78822325 http://blog.csdn.net/songqier/article/details/79188237 为一个咨询项目做准备,学习了几种对C语言函数进行mock的方法,由于C语言面向过程, 缺乏封装,继承,多态等面向对象语言的特性, 也无法利用面向对象中多态这个特性来实现mock,相对来说比java等OO的语言难于测试。 但也不是没有办法,先看例子:    下面的代码中account_update函数使用了db_update这个函数,它会直接调用数据库,是个重量级的依赖。 为了对这段代码进行测试, ... 目录一、Mock深入理解二、进阶Demo2.1 共同约定2.2 小A任务2.3 我的任务 上一篇文章(C++开发测试工具gmock使用详解——对抽象接口类进行gmock打桩并测试)主要介绍了对抽象接口类进行gmock打桩的基本流程并利用简单Demo进行测试。本文将介绍gmock打桩的进阶案例,结合上文一起食用效果更佳哦~ 一、Mock深入理解 当开发者在单元测试、模块接口测试时,当这个模块需要依赖另外一个/几个类,而这时这些个类还没有开发好(因为某些原因),这时我们就可以定义了Mock对象来模拟那些没开发好 目录一、简单Demo二、断言2.1 ASSERT和EXPECT2.2 流三、测试TEST()四、调用测试和main() 上文(C++开发测试工具gmock的安装与使用超详解)介绍了gmock的安装、配置与基本使用案例,本文将详细介绍一下gmock的基本语法,结合上文一起食用效果更佳哦~ 一、简单Demo 首先来编写一个简单Demo,编写代码之前,首先需要将解决方案的平台与目标程序一致,这里选择的是x64,然后版本也要与目标程序一致,这里选择的是release版本。 新建一个头文件,命名为demo.h,声明 ① 修改mockcpp的接口文件(追加一个宏),在mokc.h中追加MOCKER_CPP宏: #define MOCKER_CPP(api, TT) MOCKCPP_NS::mockAPI(#api, reinterpret_cast<TT>(api)) ② 使用例子: #ifndef SAMPLE_H #define SAMPLE_H #include <gtest/gtest.h> #include <mockcpp/mockcpp.hpp> #include & 对于c code,gcc 提供了编译链接选项:-Wl,-wrap 比如gcc编译时加入链接选项 -Wl,--wrap,malloc, 那么函数调用malloc的时候会调用自定义的__wrap_malloc,而原来的malloc会以__real_malloc进行调用。 所以程序需要定义一个__wrap_malloc,比如: void* __wrap_malloc(siz... 我最近发现自己处于同样的境地.我不得不写单元测试C语言编写的库,后者又依赖于其他用C语言编写的库.所以我想模拟依赖项的所有函数调用使用gmock.让我通过一个例子解释我的方法.假设要测试的代码(库A)从另一个库lib_x_function()调用一个函数:lib_a_function(){...retval = lib_x_function();...}所以,我想模拟库X.因此我编写了一个接口类... 在前面,我们看到的都是单对象单方法仅有1种预期行为定义的情况,如果定义了多个呢?假如我们在后面调用了三次Forwar(10),那么测试会报错不通过。如果调用了两次Forward(10),一次Forward(20),那么测试会通过。 目录一、简单Demo1.1 共同约定1.2 小A任务1.3 我的任务1.4 常规运行1.5 测试输出二、基本流程三、MOCK_METHOD四、EXPECT_CALL 第一篇文章(C++开发测试工具gmock的安装与使用超详解)和第二篇文章(C++开发测试工具gmock使用详解)分别对gmock的安装、配置与使用案例进行了详细介绍,本文将对抽象接口类进行gmock打桩测试进行介绍,结合上文一起食用效果更佳哦~ 一、简单Demo 首先来编写一个简单Demo,编写代码之前,首先需要将解决方案的平台与目标程序一致 曾经多次问我自己,是否需要写测试代码。 但平时的技术支持工作主要是快速阅读和调试代码,没有对代码功能测试验证的需求,所以没有留意。 直到我开始从头写一些密码学的基本功能代码,例如各种哈希算法,分组密码算法,流密码算法,分组密码的各种工作模式,各种国密算法的时候,才发现测试对于我来说,需求非常强烈。 尤其是有一次,我已经验证正确的某个代码,在此基础上实现新功能时,修改了底层代码,看起来好像没啥问题,然后在将来的某一天才发现那个修改引入了bug,又得重头查找问题的原因。如果有完整的测试,恐怕当场就能发现,而不是