c++ - 如何在不依赖注入的情况下模拟遗留函数?
问题描述
给定以下假设的遗留生产代码:
struct Foo
{
Bar bar;
bool baz()
{
return !bar.qux();
}
};
我如何模拟bar.qux()
以便它true
在一个测试和false
另一个测试中返回,而不诉诸依赖注入?
我正在使用谷歌测试框架,但想避免为依赖注入添加这么多接口。出于可测试性目的而使用过多的接口往往会使生产代码过于复杂。
解决方案
我们大概可以这样做:
#include <iostream>
#include <vector>
#include <deque>
// test/MockBarMonitorsAndControls.hpp
namespace test
{
bool const Bar_qux_default_output = true;
std::deque<bool> Bar_qux_outputs;
std::vector<int> Bar_qux_arg0_inputs;
}
// production/Bar.hpp
struct Bar
{
bool qux(int x);
};
// production/Bar.cpp
// bool Bar::qux(int x)
// {
// return static_cast<bool>(x & 2);
// }
// test/Bar.cpp
bool Bar::qux(int x)
{
test::Bar_qux_arg0_inputs.push_back(x);
if (!test::Bar_qux_outputs.empty())
{
auto result = test::Bar_qux_outputs.front();
test::Bar_qux_outputs.pop_front();
return result;
}
else
{
return test::Bar_qux_default_output;
}
}
// production/Foo.hpp
struct Foo
{
Bar bar;
int x = 9;
bool baz()
{
return !bar.qux(x);
}
void henry();
};
// test/BarTest.cpp
void TestBar1()
{
test::Bar_qux_outputs.clear();
test::Bar_qux_arg0_inputs.clear();
test::Bar_qux_outputs.push_back(false);
Foo foo;
bool pass = true;
auto result = foo.baz();
if (!result)
{
std::cout << "TEST1_ERROR: expected true result" << std::endl;
pass = false;
}
auto input = test::Bar_qux_arg0_inputs.front();
if (input != 9)
{
std::cout << "TEST1_ERROR: expected arg0 to be 9 but got " << input << std::endl;
pass = false;
}
if (pass)
{
std::cout << "TEST1 PASS" << std::endl;
}
else
{
std::cout << "TEST1 FAIL" << std::endl;
}
}
// test/BarTest.cpp
void TestBar2()
{
test::Bar_qux_outputs.clear();
test::Bar_qux_arg0_inputs.clear();
test::Bar_qux_outputs.push_back(true);
Foo foo;
foo.x = 21;
bool pass = true;
auto result = foo.baz();
if (result)
{
std::cout << "TEST2_ERROR: expected false result" << std::endl;
pass = false;
}
auto input = test::Bar_qux_arg0_inputs.front();
if (input != 21)
{
std::cout << "TEST2_ERROR: expected arg0 to be 21 but got " << input << std::endl;
pass = false;
}
if (pass)
{
std::cout << "TEST2 PASS" << std::endl;
}
else
{
std::cout << "TEST2 FAIL" << std::endl;
}
}
int main()
{
TestBar1();
TestBar2();
return 0;
}
这是示例输出:
TEST1 PASS
TEST2 PASS
推荐阅读
- python-3.x - 如何为图像 vk 添加描述?
- reporting-services - SSRS:“包含错误:[BC302205] 预期语句结束。”
- vmware - 打开虚拟机时出错。vmx 文件已损坏
- wordpress - How to fix Gutenberg's Convert to Blocks?
- php - 如何在yii2的控制器动作中使用return而不是echo
- elasticsearch - How to use standard tokenizer with preserve_original?
- spring-boot - Springboot + Drools, java.lang.RuntimeException: Illegal class for global
- azure - No SnapshotStart detected. Might need more exceptions to trigger snapshot collector
- php - PHP IF 语句允许 A、B、C 和 D
- python - 为什么我的代码无法从我的 txt 文件中读取 3 位数字?