gmock和链接错误

时间:2015-04-05 18:46:16

标签: c++ unit-testing makefile gmock

当我尝试用我的生产c ++代码类和模拟对象编译单元测试时,我得到链接错误。我正在使用make文件和clang编译器(osx命令行)。

这是简化的例子。谢谢你能帮我解决这个问题。 文件夹结构如下:

生产代码 - >单元测试代码 - > Gmock和GTest文件夹

1)生产代码A类将进行单元测试。

myclass_a.h:

#ifndef MYCLASS_A_H
#define MYCLASS_A_H

#include "myclass_b.h"

class MyClass_A
{
public:
    MyClass_A();
    virtual void DoBThing();

private:
    MyClass_B secondClass;
};

#endif // MYCLASS_A_H

myclass_a.cpp:

#include "myclass_a.h"

MyClass_A::MyClass_A()
{
}

void MyClass_A::DoBThing()
{
    secondClass.DoThis();
}

2)生产代码类B.模拟对象将派生它。

myclass_b.h:

#ifndef MYCLASS_B_H
#define MYCLASS_B_H

class MyClass_B
{
public:
    MyClass_B();
    virtual void DoThis();
};

#endif // MYCLASS_B_H

myclass_b.cpp:

#include "myclass_b.h"

MyClass_B::MyClass_B()
{
}

void MyClass_B::DoThis()
{
}

3)单元测试代码

MyClassA_UT.cpp:

#include "Mock-MyClassB.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../myclass_a.h"

TEST(ClassACategory,Test1)
{
    MockMyClass_B classB;
    EXPECT_CALL(classB, DoThis());
    MyClass_A classA;

    classA.DoBThing();
}

4)模拟对象

模拟-MyClassB.h:

#include "gmock/gmock.h"  // Brings in Google Mock.
#include "../myclass_b.h"

class MockMyClass_B : public MyClass_B {
 public:
  MOCK_METHOD0(DoThis, void());
};

5)项目的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 = ./gtest-1.7.0

# Points to the root of Google Mock, relative to where this file is.
# Remember to tweak this if you move this file.
GMOCK_DIR = ./gmock-1.7.0

# Where to find user code.
USER_DIR = ./
PRODUCTION_CODE_DIR = ../

# 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

# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
TESTS = UnitTest

# 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 : $(TESTS)

clean :
    rm -f $(TESTS) gmock.a gmock_main.a *.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

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

gmock.a : gmock-all.o gtest-all.o
    $(AR) $(ARFLAGS) $@ $^

gmock_main.a : gmock-all.o gtest-all.o gmock_main.o
    $(AR) $(ARFLAGS) $@ $^

# Builds a sample test.

myclass_a.o : $(PRODUCTION_CODE_DIR)/myclass_a.cpp $(PRODUCTION_CODE_DIR)/myclass_a.h $(GMOCK_HEADERS)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(PRODUCTION_CODE_DIR)/myclass_a.cpp

MyClassA_UT.o : $(USER_DIR)/MyClassA_UT.cpp $(GMOCK_HEADERS)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/MyClassA_UT.cpp

UnitTest : MyClassA_UT.o myclass_a.o gmock_main.a
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

6)链接错误:

ar rv gmock_main.a gmock-all.o gtest-all.o gmock_main.o
ar: creating archive gmock_main.a
a - gmock-all.o
a - gtest-all.o
a - gmock_main.o
c++ -isystem ./gtest-1.7.0/include -isystem ./gmock-1.7.0/include -g -Wall -Wextra -pthread -lpthread MyClassA_UT.o myclass_a.o gmock_main.a -o UnitTest
clang: warning: argument unused during compilation: '-pthread'
Undefined symbols for architecture x86_64:
  "MyClass_B::DoThis()", referenced from:
      MyClass_A::DoBThing() in myclass_a.o
  "MyClass_B::MyClass_B()", referenced from:
      MyClass_A::MyClass_A() in myclass_a.o
  "MyClass_B::MyClass_B()", referenced from:
      MockMyClass_B::MockMyClass_B() in MyClassA_UT.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [UnitTest] Error 1

如果我将B类对象添加到makefile,那么将调用B类的方法而不是mock方法。

编辑,如果我添加了B类,编译通过但测试用例失败:

./UnitTest
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ClassACategory
[ RUN      ] ClassACategory.Test1
.//MyClassA_UT.cpp:9: Failure
Actual function call count doesn't match EXPECT_CALL(classB, DoThis())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] ClassACategory.Test1 (0 ms)
[----------] 1 test from ClassACategory (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] ClassACategory.Test1

0 个答案:

没有答案