我被这几天困扰了。我正在我的一个班级上进行单元测试,以确保一切正确。
然而,在比较对象的名称时,我遇到了一个非常奇怪的'错误'。 我调用构造函数时设置名称。根据我传入的注释正确设置名称。但是在这种情况下,BOOST_CHECK失败
为了表明这有多奇怪,这里是调试器中两个字符串的值:
Fdim.name() // "F Diminished"
BOOST_CHECK(Fdim.name() == "F Diminished"); // this fails
以下是两个字符串的规范,取自调试器:
Fdim.name()
// size - 12, capacity - 15,
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]
"F Diminished" stored inside a variable (to see specs of string)
// size - 12, capacity - 15,
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]
正如您所看到的,字符串相同,但==和.compare都失败了。
这是更奇怪的事情:
std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r); // RETURNS 0, everytime
BOOST_CHECK(val == 0); // fails
BOOST_CHECK(val == ((unsigned) 0));// fails
我完全傻眼了。当我比较字符串时,val总是返回0(所以它们相等)但是当我比较时,val!= 0?
有谁知道问题可能是什么? 我应该知道的字符串是否有任何属性可能会导致这种比较检查?
修改* * * 字符串存储为std :: string,我不使用char *或cstring。 member _name是std :: string。
这是BOOST OUTPUT:
c:/directory etc(64): error in "ChordIdentification": check val == 0 failed
c:/directory etc(65): error in "ChordIdentification": check n == r failed
c:/directory etc(66): error in "ChordIdentification": check val == ((unsigned) 0) failed
c:/directory etc(67): error in "ChordIdentification": check Fdim.name() == "F Diminished" failed
这是测试用例的代码,只是为了确保人们知道val,n和r是什么:
BOOST_AUTO_TEST_CASE(ChordIdentification)
{
MAKE_NOTE(Db, 'D', FLAT); // macro that creates a note
MAKE_NOTE(F, 'F', NATURAL);
MAKE_NOTE(Ab, 'A', FLAT);
MAKE_NOTE(Cb, 'C', FLAT);
Chord DbMajor7 = Chord(Cb, Ab, F, Db);
Chord Fdim = Chord(Ab, Cb, F);
CHORD_TEST(DbMajor7, "Db Dominant7", MAJ, THIRD_INVERSION, DOMINANT7); macro of several boost tests, checking members. This test passes completely for this instance of chord. name() check is passed
std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);
//if (val == 0)
BOOST_CHECK(val == 0);
BOOST_CHECK(n == r);
BOOST_CHECK(Fdim.name() == std::string("F Diminished")); // these strings fail to compare. no idea why, lengths are same, chars same?????
BOOST_CHECK(std::strcmp(Fdim.name(), "F Diminished") == 0);
CHORD_TEST(Fdim, "F Diminished", DIM, FIRST_INVERSION, DIMINISHED); // partially successful, again the string comparison is responsible for this
}
答案 0 :(得分:3)
我终于发现了为什么会这样。这与调试器无法确定它正在尝试评估的子类实例的事实有关。
正在通过地图识别和弦,具有多态键,具有抽象基类(Composite_Key),子(Composite_Key_2Intervals)和来自该子项的子(Composite_Key_3Intervals)
失败的原因是,对于一个密钥是否确实是3个间隔或2的任何类型的测试总是返回true,因为3个间隔:2个间隔。编译器无法接收到这一点,并且始终返回查找表中找到的错误值。
此外,地图从未在调试器模式下排序,因此插入键的顺序保持不变。但实际上它们正在重新调整,这导致整个评估时调试完全错误。
为了解决这个问题,我现在确保这两个类只从抽象基类继承,因此它们之间没有任何关联。现在所有测试都通过,一切都恢复正常。
此问题的原因仅仅是调试器。它没有适当评估。
答案 1 :(得分:1)
如果我们看一下:
BOOST_CHECK(Fdim.name() == "F Diminished")
然后Fdim.name()是一个C风格的字符串,我希望,因此只是一个指向字符数组的指针 - 该字符数组的地址(很可能)与您文字字符串中的字符串不同BOOST_CHECK()
。
你可以通过以下方式修复它:
BOOST_CHECK(Fdim.name() == string("F Diminished"))
或
BOOST_CHECK(strcmp(Fdim.name(), "F Diminished") == 0)