- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我开始在 Windows 上测试 GoogleMock(1.8.0 版)。我想展示一个它不是线程安全的例子。成功证明后,我想证明相同的测试在 Linux 上运行良好。然而,那失败了。这与我的预期不符。由于 GoogleMock 文档说它在具有 pthreads 的系统上是或者应该是线程安全的,因此它在 Linux 上应该是线程安全的。我确实必须将 -pthread
添加到链接器命令行以构建可执行文件。这意味着 GoogleMock 或 GoogleTest 确实使用了 pthreads。
这是我用来测试的代码:
#include <thread>
#include <vector>
#include "gmock/gmock.h"
class Dummy
{
public:
virtual void SomeMethod(int) {}
};
class DummyMock : public Dummy
{
public:
MOCK_METHOD1(SomeMethod, void(int));
};
using ::testing::Exactly;
constexpr static int nrCallsPerThread = 100 * 1000;
constexpr static int nrThreads = 10;
TEST(SomeTest, Test100)
{
DummyMock dummy;
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
threads.emplace_back([&dummy, i]
{
for (int j = 0; j < nrCallsPerThread; j++)
{
dummy.SomeMethod(i);
}
});
}
for (auto& t: threads)
{
t.join();
}
}
int main(int argc, char** argv)
{
testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
问题是,在 Linux 上,并不是每次执行都公开。但是使用 --gtest_repeat=100
运行可执行文件的命中率接近 100%。
在 Windows 上,使用 Visual Studio 2015,如果收到 Debug Assertion Failed!
消息,其中包含 Expression: vector iterator not decrementable
。
在 Linux Ubuntu 17.04 上,当我从命令行运行调试构建时,我得到 [ FATAL ] ../googletest-release-1.8.0/googletest/include/gtest/internal/gtest-port。 h:1928::pthread_mutex_lock(&mutex_) 失败,错误 22
。
在 Linux 上的调试器中运行时,程序(通常)在 gtest-port.h 的第 1100 行中断,也就是此调用堆栈中的第 2 行:
0 0x5555555a6633 testing::Cardinality::ConservativeUpperBound() const () (??:??)
1 0x5555555a1a13 testing::internal::ExpectationBase::CheckActionCountIfNotDone() const () (??:??)
2 0x555555563f98 testing::internal::TypedExpectation<void (int)>::ShouldHandleArguments(std::tuple<int> const&) const(this=0x5555557f58a0, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1100)
3 0x55555556397d testing::internal::FunctionMockerBase<void (int)>::FindMatchingExpectationLocked(std::tuple<int> const&) const(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1723)
4 0x555555563578 testing::internal::FunctionMockerBase<void (int)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*)(this=0x7fffffffde38, untyped_args=0x7fffde7fbe14, untyped_action=0x7fffde7fb7d0, is_excessive=0x7fffde7fb7c7, what=0x7fffde7fb900, why=0x7fffde7fba90) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1687)
5 0x5555555a265e testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) () (??:??)
6 0x55555555fcba testing::internal::FunctionMockerBase<void (int)>::InvokeWith(std::tuple<int> const&)(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1585)
7 0x55555555f16c testing::internal::FunctionMocker<void (int)>::Invoke(int)(this=0x7fffffffde38, a1=1) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h:101)
8 0x55555555ecb6 DummyMock::SomeMethod(this=0x7fffffffde30, gmock_a1=1) (/home/jos/Programming/ThreadSafeGMock/main.cpp:16)
9 0x55555555d31e SomeTest_Test100_Test::<lambda()>::operator()(void) const(__closure=0x5555557f5478) (/home/jos/Programming/ThreadSafeGMock/main.cpp:36)
10 0x55555555de98 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>)(this=0x5555557f5478) (/usr/include/c++/6/functional:1391)
11 0x55555555de22 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::operator()(void)(this=0x5555557f5478) (/usr/include/c++/6/functional:1380)
12 0x55555555ddf2 std::thread::_State_impl<std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()> >::_M_run(void)(this=0x5555557f5470) (/usr/include/c++/6/thread:197)
13 0x7ffff7b0a83f ??() (/usr/lib/x86_64-linux-gnu/libstdc++.so.6:??)
14 0x7ffff76216da start_thread(arg=0x7fffde7fc700) (pthread_create.c:456)
15 0x7ffff735b17f clone() (../sysdeps/unix/sysv/linux/x86_64/clone.S:105)
既然应该是线程安全的,我怀疑我做错了什么。但我没有看到什么。还是我遇到了 GoogleTest 或 GoogleMock 中的错误?
最佳答案
来自精品手册:
Important note: Google Mock requires expectations to be set before the mock functions are called, otherwise the behavior is undefined. In particular, you mustn't interleave EXPECT_CALL()s and calls to the mock functions.
您的原始代码在我的系统 (cygwin) 上间歇性地失败并出现错误 22,或者有时没有任何消息/错误代码。此修改完美无缺:
for (int i = 0; i < nrThreads; i++)
{
EXPECT_CALL(dummy, SomeMethod(i)).Times(Exactly(nrCallsPerThread));
}
std::vector<std::thread> threads;
for (int i = 0; i < nrThreads; i++)
{
threads.emplace_back([&dummy, i] ...
关于c++ - GoogleMock 在 Linux 上不是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44750012/
与其说是一个问题,不如说是一个知识共享。 根据 GoogleMock FAQ无法模拟可变参数函数,因为不知道该函数将提供多少参数。 这是真的,但在大多数情况下,人们知道从被测系统调用可变参数函数有多少
我如何模拟一个返回新对象的方法,该对象的构造函数将方法的参数之一作为其自身的参数? // ObjectA::ObjectA(MockedObject arg1, ObjectB* arg2); //
我有一个模拟这样的方法: MOCK_METHOD2(setValue, int(int notImportant, unsigned int value)); MOCK_METHOD2(getValu
我有一个模拟这样的方法: MOCK_METHOD2(setValue, int(int notImportant, unsigned int value)); MOCK_METHOD2(getValu
我想使用 GoogleMock 模拟如下服务: class Request { int req_id; int request; }; class Response { int
我们正在为现有代码库编写单元测试。我们使用 Google Test/Google Mock 进行测试,C++11 和 Eclipse CDT 与 gcc 编译器。 我们的一个类聚合了一个 Boost
我在运行 make 时不断收到这些错误: debug/main.o: In function `MockMQAdapter::MockMQAdapter()': /source/Tests/tests
#include "gtest/gtest.h" #include "gmock/gmock.h" class Turtle{ public: int foo(); }; i
我是 google mock 的初学者,我不确定如何使用它和概念。 如果我试图测试一个类中的方法,而这个类正在调用不同类中的一些其他方法。我是否需要从我的测试方法调用的不同类中模拟所有这些方法。这是一
看起来我在尝试模拟接口(interface)时无法使用虚拟继承。我需要使用虚拟继承,因为我的代码依赖于第三方库。第 3 方库使用虚拟继承通过父级从一个子级转换为另一个。我们需要能够根据 3rd 方库的
我有一个 Foo 类,它引用多个其他 IBar 类型的对象。该类有一个方法 fun,它需要至少在其中一个 IBar 上调用方法 frob。我想用模拟的 IBar 编写一个测试来验证这个要求。我正在使用
我开始使用 googletest 和 googlemock 库,但遇到无法解决的问题。我有这样的代码: class Painter { public: void DrawSomething()
我在工作中使用 googlemock。我们经常使用 EXPECT_THROW、EXPECT_NO_THROW 等... 我的问题是,当一个函数被包装在 EXPECT_NO_THROW 中但实际上抛出异
我想模拟一个返回复杂数据类型的方法 class aClass { public: virtual const QMap aMethod() const; } class MockaClass :
我尝试模拟表示 NVRAM 的现有类的行为和 API。 API 是: bool Init(Uint8* dataPointer); bool Store(); //Writes the data fr
是否可以从同一类的其他方法调用中模拟方法调用?我是 C++ 的新手(主要是 C 开发人员)并且是 googlemock 和 Google Test 的新手所以如果在其他地方回答了这个问题并且我不明白答
我创建了一个 googlemock 文本夹具类,在 SetUp 中我使用 new 创建了两个对象。在拆解中,如果我什么都不删除,我只会得到其中一个对象的内存泄漏错误。 class MissileLau
我有一个小类: struct Command { uint8_t cmdId; uint8_t len; uint8_t payload[MAX_PAYLOAD]; }; 我只
我已经使用 gtest 一段时间了,但最近想尝试一下 gmock。我正在尝试使用返回值的方法模拟类,但也通过引用在输出参数中返回一些东西。这是我的小代码。 #include #include "gm
我正在测试我的类是否使用正确的参数调用模拟类上的方法。我已经建立了一个基本的期望: // mListener is a mocked object // This expectation accept
我是一名优秀的程序员,十分优秀!