如何使用 Symbol not found 错误解决 Gmock?

How to address Gmock with Symbol not found error?

我试图从 donsoft.io's example

制作一个最小的 gmock 测试用例

文件结构简单:

my_workspace/
├── BUILD
├── WORKSPACE
├── coinflipper.cc
├── coinflipper.h
├── mockrng.cc
├── mockrng.h
└── rng.h

我在尝试通过 $ bazel test --test_output=all //:mockrng

进行编译时遇到此错误
$ bazel test --test_output=all //:mockrng
INFO: Analyzed target //:mockrng (0 packages loaded, 0 targets configured).
INFO: Found 1 test target...
FAIL: //:mockrng (see /private/var/tmp/_bazel_pvd/83a142a3c9781856c99d4f0c60c1af76/execroot/__main__/bazel-out/darwin-fastbuild/testlogs/mockrng/test.log)
INFO: From Testing //:mockrng:
==================== Test output for //:mockrng:
dyld: Symbol not found: __ZTI3Rng
  Referenced from: /private/var/tmp/_bazel_pvd/83a142a3c9781856c99d4f0c60c1af76/sandbox/darwin-sandbox/21/execroot/__main__/bazel-out/darwin-fastbuild/bin/mockrng.runfiles/__main__/mockrng
  Expected in: flat namespace
 in /private/var/tmp/_bazel_pvd/83a142a3c9781856c99d4f0c60c1af76/sandbox/darwin-sandbox/21/execroot/__main__/bazel-out/darwin-fastbuild/bin/mockrng.runfiles/__main__/mockrng
================================================================================
Target //:mockrng up-to-date:
  bazel-bin/mockrng
INFO: Elapsed time: 0.256s, Critical Path: 0.13s
INFO: 2 processes: 2 darwin-sandbox.
INFO: Build completed, 1 test FAILED, 2 total actions
//:mockrng                                                               FAILED in 0.1s
  /private/var/tmp/_bazel_pvd/83a142a3c9781856c99d4f0c60c1af76/execroot/__main__/bazel-out/darwin-fastbuild/testlogs/mockrng/test.log

INFO: Build completed, 1 test FAILED, 2 total actions

我的代码与donsoft.io基本相同,只是想知道我是否遗漏了什么?

coinflipper.cc

#include "coinflipper.h"

CoinFlipper::CoinFlipper(Rng* rng) : d_rng(rng) {}

CoinFlipper::Result CoinFlipper::flipCoin() const {
  const double val = d_rng->generate(0.0, 1.0);
  return (val < 0.5) ? HEADS : TAILS;
}

coinflipper.h

#include "rng.h"

class CoinFlipper {
 private:
  Rng* d_rng;  // held, not owned

 public:
  enum Result { HEADS = 0, TAILS = 1 };

  explicit CoinFlipper(Rng* rng);
  Result flipCoin() const;
};

mockrng.cc

#include "mockrng.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "coinflipper.h"

TEST(CoinFlipper, ShouldReturnHeadsIfRandValueIsLessThanProbability) {    
    MockRng rng;
    
    EXPECT_CALL(rng, generate(::testing::DoubleEq(0.0), ::testing::DoubleEq(1.0)))
        .Times(::testing::Exactly(1))
        .WillOnce(::testing::Return(0.25));

    CoinFlipper coinFlipper(&rng);
    CoinFlipper::Result result = coinFlipper.flipCoin();
    EXPECT_EQ(CoinFlipper::HEADS, result);    
}

mockrng.h

#include "gmock/gmock.h"
#include "rng.h"

class MockRng : public Rng {
  public:
    MOCK_METHOD2(generate, double(double, double));
};

rng.h

#ifndef RNG_H
#define RNG_H
class Rng {
 public:
  virtual ~Rng();
  virtual double generate(double min, double max) = 0;
};
#endif

建造

load("@rules_cc//cc:defs.bzl", "cc_test")

cc_test(
  name = "mockrng",
  size = "small",
  srcs = ["mockrng.cc", "mockrng.h", "rng.h","coinflipper.h","coinflipper.cc"],
  deps = ["@com_google_googletest//:gtest_main"],
)

缺少 Rng::~Rng() 的定义部分,稍微修复一下即可:

#ifndef RNG_H
#define RNG_H
class Rng {
 public:
  virtual ~Rng() {};
  virtual double generate(double min, double max) = 0;
};
#endif

顺便问一下,您使用的是什么版本的编译器?现代编译器会给我们明确的错误信息:

undefined reference to `Rng::~Rng()'

而不是你得到的:

dyld: Symbol not found: __ZTI3Rng

一些无关紧要的建议: 一些头文件缺少保护处理器,容易出错,需要修复。