简体   繁体   English

如何在不诉诸依赖注入的情况下模拟遗留函数?

[英]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.

相关问题 如何不使用std :: function来存储函数对象? - How to store a function object without resorting to std::function? 如何指定返回类的 constexpr 函数的类型(不使用 auto 关键字) - How to specify type of a constexpr function returning a class (without resorting to auto keyword) 使用 unique_ptr 进行依赖注入来模拟 - Dependency injection with unique_ptr to mock 在 C++ 中没有依赖注入的情况下模拟在函数内部创建的外部依赖对象 - Mocking External Dependency object created inside a function without dependency injection in c++ 如何不借助const_cast打开HINSTANCE? - How to switch on HINSTANCE without resorting to const_cast? 如何模拟没有类的函数? - How to mock a function which is without class? C ++ Google Mock指南提到的依赖注入 - Dependency Injection mentioned by C++ Google Mock guide 如何模拟依赖项的成员变量? - How to mock a member variable of dependency? 使用可变参数模板成员 function 的 class 的依赖注入 - Dependency injection of class with variadic template member function 是否可以在 C# 中等待异步 C/C++ function 而无需诉诸 Task.Run()? - is it possible to make an asynchronous C/C++ function awaitable in C# without resorting to Task.Run()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM