[英]How to mock a legacy function without resorting to dependency injection?
Given the following hypothetical legacy production code:鉴于以下假设的遗留生产代码:
struct Foo
{
Bar bar;
bool baz()
{
return !bar.qux();
}
};
How do I mock bar.qux()
so that it returns true
in one test and false
in another test, without resorting to dependency injection ?我如何模拟bar.qux()
以便它在一个测试中返回true
并在另一个测试中返回false
,而无需求助于依赖注入?
I'm using Google Test framework, but want to avoid adding so many interfaces for dependency injections.我正在使用Google Test框架,但希望避免为依赖注入添加如此多的接口。 Too many interfaces for the purpose of testability tends to make the production code overly complex.出于可测试性目的的太多接口往往会使生产代码过于复杂。
We can probably do something like this:我们大概可以这样做:
#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;
}
Here's the sample output:这是示例输出:
TEST1 PASS
TEST2 PASS
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.