对于单元测试,有没有一种更改const变量的值的黑客方法?

2022-08-26 00:00:00 c++ c++11 const-cast googletest

我有一个C++11头文件,它有一个声明为my_const_value的常量值。以及一个名为GetValue的函数,该函数使用const值运行复杂逻辑并返回期望值。

我想用my_const_value的不同值对GetValue进行单元测试。

我知道这不可取,但为了编写GetValue的单元测试,我希望使用不同的my_const_value值来测试GetValue。在C++中是否有一些类似黑客的方法来更改常量的值,即使它是常量?

//MyHeader.hpp
namespace myheader {

const int my_const_value = 5;

int GetValue() {
    // In real-world, lets say below line of code is a complex logic that needs to be tested by a unit test
    return /my_const_value * 5) / 25;
}

}

#include "MyHeader.hpp"
#include <gtest/gtest.h>

TEST(MyHeaderTest, Testing_Something) {
    EXPECT_EQ(1, myheader::GetValue()); // This is okay

    // I want to test that in the future is the value of my_const_value changes to something else then 
    // myheader::GetValue returns the expected result. But of course, I cannot change my_const_value because it is a const.
    // Is there a way to hack around this for a unit test? Is there a way that I could still hack and change the value of my_const_value?
    myheader::my_const_value = 25;
    EXPECT_EQ(5, myheader::GetValue());
}

我知道我可以const_castmy_const_value赋给一个非常量变量。但这在这里帮不上忙。如果有什么办法可以通过使用指针或其他方法来更改my_const_value的值,那就回答了我的问题。


解决方案

我知道您正在寻找如何丢弃常量的方法,但我可能会采取不同的方法。

你在评论中说:

好吧。我已经给出了我的理由。我正在测试GetValue中的逻辑。我已将my_const_value声明为const,但将来有人更改该值时,可以将其从5更改为其他值。

如果变量是const,并且在没有传递给它的情况下参与函数内的表达式,那么这些更改通常不应该定期发生,也不应该预期。如果将myheader::my_const_value视为配置值,并且该配置值可能随时会更改,则应将其传递给在表达式中使用它的函数。

所以从测试的角度来看,我同意idclev 463035818答案中的建议,将函数分成两个部分,一个是带参数的可测试部分,另一个是使用常量的部分。

一个测试,用于测试代码当前的行为(它应该具有什么常量)

TEST(MyHeaderTest, Testing_Something1) {
    EXPECT_EQ(5, myheader::my_const_value)
    EXPECT_EQ(1, myheader::GetValue());
    
}

一个用于一般测试:

TEST(MyHeaderTest, Testing_Something2) {
    EXPECT_EQ(1, myheader::GetValue_impl(5));
    EXPECT_EQ(5, myheader::GetValue_impl(25));
    // …
}
这样,如果GetValue使用的计算起作用,您就有了通用测试。对于您代码的当前版本,myheader::GetValue()的值是预期的值。

相关文章