使用 fakeit 模拟第三方库
Mocking an 3rd party library using fakeit
我正在编写自己的 library/class,它使用了第 3 方库。我想为自己的 class 编写测试,并模拟第 3 方库。在其中一个测试中,我想确保当我的 class 上的一个函数被调用时,第 3 方库中的另一个函数也开始被调用。我认为 FakeIt library 是测试这个的好主意。
这是我的测试代码示例:
#include "MyTest.h"
#include "fakeit.hpp"
using namespace fakeit;
int main() {
MyTest dt;
Mock<ExternLib> mock;
Fake(Method(mock, someFunc));
ExternLib& el = mock.get();
dt.begin();
Verify(Method(mock, someFunc));
return 0;
}
当这是 运行 时,它会抛出 fakeit::SequenceVerificationException
和
Expected pattern: mock.someFunc( Any arguments )
Expected matches: at least 1
Actual matches : 0
Actual sequence : total of 0 actual invocations.
很明显,模拟没有工作,也没有调用它的方法。知道如何模拟这个 class 并验证它的方法是否被调用了吗?
MyTest.cpp 只是一个简单的测试,将是我的全部 library/class:
#include "MyTest.h"
MyTest::MyTest() {
_manager = new ExternLib();
}
void MyTest::begin() {
result = _manager->someFunc();
}
它的头文件:
#pragma once
#include "Externlib.h"
class MyTest {
public:
MyTest();
virtual void begin();
int result = 3;
private:
ExternLib *_manager;
};
ExternLib 是第 3 方库的模拟版本。我的实现实现了真实接口的基本必需品,而这些函数实际上什么都不做。该实现实际上基本上只是为了满足 #include Externlib.h
语句。
这是我的 Externlib.cpp:
#include "Externlib.h"
ExternLib:: ExternLib() {}
int ExternLib::someFunc() {
return 5;
}
和头文件:
#pragma once
class ExternLib {
public:
ExternLib();
virtual int someFunc();
};
解释fakeit::SequenceVerificationException
:
使用行 Mock<ExternLib> mock;
,您创建了一个新的 ExternLib
实例,它永远不会被 MyTest
调用(因为 MyTest
创建了它自己的 ExternLib
实例)。
要测试调用,您可以
- 将存储在
_manager
中的 ExternLib 实例公开给您的测试,方法是使它成为 public 或添加访问器,然后 spy on it(Mock<ExternLib> mock(MyTest._manager);
或类似)
- 用您的 ExternLib Mock 实例交换存储在
MyTest::_manager
中的 ExternLib 实例。
但这意味着为了可测试性而暴露您的被测对象的内部工作机制,这可能是不希望的。
我以前从未使用过伪造它,但是,当您将 MyTest 设置为可注入后将 mock.get() 传递给 MyTest 时,它可能会起作用。
class MyTest {
public:
MyTest(ExternaLib* lib) : _manager(lib) {}
}
我正在编写自己的 library/class,它使用了第 3 方库。我想为自己的 class 编写测试,并模拟第 3 方库。在其中一个测试中,我想确保当我的 class 上的一个函数被调用时,第 3 方库中的另一个函数也开始被调用。我认为 FakeIt library 是测试这个的好主意。
这是我的测试代码示例:
#include "MyTest.h"
#include "fakeit.hpp"
using namespace fakeit;
int main() {
MyTest dt;
Mock<ExternLib> mock;
Fake(Method(mock, someFunc));
ExternLib& el = mock.get();
dt.begin();
Verify(Method(mock, someFunc));
return 0;
}
当这是 运行 时,它会抛出 fakeit::SequenceVerificationException
和
Expected pattern: mock.someFunc( Any arguments )
Expected matches: at least 1
Actual matches : 0
Actual sequence : total of 0 actual invocations.
很明显,模拟没有工作,也没有调用它的方法。知道如何模拟这个 class 并验证它的方法是否被调用了吗?
MyTest.cpp 只是一个简单的测试,将是我的全部 library/class:
#include "MyTest.h"
MyTest::MyTest() {
_manager = new ExternLib();
}
void MyTest::begin() {
result = _manager->someFunc();
}
它的头文件:
#pragma once
#include "Externlib.h"
class MyTest {
public:
MyTest();
virtual void begin();
int result = 3;
private:
ExternLib *_manager;
};
ExternLib 是第 3 方库的模拟版本。我的实现实现了真实接口的基本必需品,而这些函数实际上什么都不做。该实现实际上基本上只是为了满足 #include Externlib.h
语句。
这是我的 Externlib.cpp:
#include "Externlib.h"
ExternLib:: ExternLib() {}
int ExternLib::someFunc() {
return 5;
}
和头文件:
#pragma once
class ExternLib {
public:
ExternLib();
virtual int someFunc();
};
解释fakeit::SequenceVerificationException
:
使用行 Mock<ExternLib> mock;
,您创建了一个新的 ExternLib
实例,它永远不会被 MyTest
调用(因为 MyTest
创建了它自己的 ExternLib
实例)。
要测试调用,您可以
- 将存储在
_manager
中的 ExternLib 实例公开给您的测试,方法是使它成为 public 或添加访问器,然后 spy on it(Mock<ExternLib> mock(MyTest._manager);
或类似) - 用您的 ExternLib Mock 实例交换存储在
MyTest::_manager
中的 ExternLib 实例。
但这意味着为了可测试性而暴露您的被测对象的内部工作机制,这可能是不希望的。
我以前从未使用过伪造它,但是,当您将 MyTest 设置为可注入后将 mock.get() 传递给 MyTest 时,它可能会起作用。
class MyTest {
public:
MyTest(ExternaLib* lib) : _manager(lib) {}
}