【问题标题】:Mocking External Dependency object created inside a function without dependency injection in c++在 C++ 中模拟没有依赖注入的函数内部创建的外部依赖对象
【发布时间】:2020-09-04 07:01:16
【问题描述】:

我正在尝试用 C++ 编写单元测试,但在使用 Fakeit 为外部依赖项创建模拟对象时遇到了问题。所以我们有一个类似于下面的类:

class A 
{
    int test_method()
    {
        B obj;
        return obj.sendInt()
    }
};

class B
{
    int sendInt()
    {
        return 5;
    }
};

现在假设我想为 test_method()A 编写一个单元测试。当我们调用obj.sendInt() 时,我想模拟它并返回一个不同的值。我尝试使用 fakeit,但无法找到解决方案。

我知道如果我们尝试通过构造函数或在 setter 方法中对 B 进行依赖注入,这将得到解决,但我不想这样做,因为它需要对 A 的现有消费者进行一些重构.

对于 Java 中的类似场景,我会使用 PowerMockito 并使用 PowerMockito.whenNew 实现相同的效果

B mock = Mockito.mock(B.class);
PowerMockito.whenNew(B.class).withAnyArguments().thenReturn(mock);
Mockito.when(mock.test()).thenReturn(2);
A obj=new A();
assertEquals(obj.test(), 2);

【问题讨论】:

    标签: c++ unit-testing googlemock catch2 fakeit


    【解决方案1】:

    最简单的方法是使用依赖注入。我不认为 C++ 有任何类似于 PowerMockito 的东西(例如,不可能像 PowerMockito 允许 java 那样模拟静态方法/函数)。

    如果问题仅在于通过 ctor 或 setter 方法进行依赖注入,请考虑使用 hi-perf dependency injection,即使用模板注入 mock。

    如果 class A 根本无法修改,但您拥有 class B,请考虑将 class B 移至单独的静态库:一个用于生产(例如,libBprod),另一个用于测试(libBtest )。在生产中,您可以链接到 libBprod 并在测试中链接到 libBtest。在libBtest 中,您可以在后台将class B 设为单例。不过,这是相当多的工作。

    如果class Aclass B 都不能修改,那我就没有主意了——你需要以某种方式重构代码的某些部分。

    【讨论】:

    • 谢谢夸拉。我知道这可以通过模板解决,但我想避免任何方式的 DI,因为我不想改变消费者。我解决的一种方法是将初始化 B 并调用其方法的代码移动到私有方法并使用 gmock 模拟此私有方法。
    【解决方案2】:

    我将初始化 B 并调用其方法的代码移至私有方法,并使用 gmock 模拟了此私有方法

    class A 
    {
    
    int test_method()
    {
    return getBValue();
    }
    int getBValue()
    {
    B obj;
    return obj.sendInt()
    }
    
    }
    

    我的测试方法看起来像,

    Class MockA :: A
    {
    public:
    MOCK_METHOD(int,getBValue,(),override);
    
    }
    
    TEST_CASE("Test1")
    {
    MockA mock;
    ON_CALL(mock, getBValue()).WillByDefault(Return(10));
    REQUIRE(mock.test_method()==10);
    }
    

    【讨论】:

    • 您需要将virtual添加到getBValue
    猜你喜欢
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    相关资源
    最近更新 更多