【问题标题】:How to test that a sequence generator will generate the expected item?如何测试序列生成器是否会生成预期的项目?
【发布时间】:2019-11-07 12:34:08
【问题描述】:

我有一个生成A 的类B。我知道在一个特定的设置中,如果我调用它 3 次,它会生成一个特定的 A (expected_a) 实例,但我不知道序列的哪个位置。

我想写一些单元测试代码,例如:

A expected_a(...);

B b;

std::set<A> set_of_a{ b.nextA() , b.nextA(), b.nextA() };

EXPECT_TRUE(set_of_a.count(expected_a) == 1);

但是使用set 需要实现A::operator&lt;()operator&lt; 可以很容易地实现,但是我正在编写生产代码来满足测试,这是我不喜欢/不想做的。

我尝试使用 unordered_set,它不需要 operator&lt;,但确实需要实现 hash()

顺便说一句 A::operator= 已经在生产中实现。

我可以使用 vector 并遍历,手动搜索,但这似乎有点笨拙。

我怎样才能优雅地编写这个测试而不必实现测试特定的操作符?

【问题讨论】:

  • 您可能会将该 A 扩展为 TestA 类型,该类型仅将该运算符添加到实际类的顶部。该实现将特定于测试,不会出现在实际的生产代码中。

标签: c++ unit-testing stl set containers


【解决方案1】:

您可以简单地使用另一个容器和std::count

A expected_a(...);
B b;

std::array<A, 3> arr_of_as{ b.nextA() , b.nextA(), b.nextA() };

EXPECT_TRUE(std::count(std::begin(arr_of_as), std::end(arr_of_as), expected_a) > 0);

你甚至不能存储它们:

A expected_a(...);
B b;

int count_a = 0;
for (int i = 0; i < 3; ++i) {
    count_a += b.nextA() == expected_a;
}
EXPECT_TRUE(count_a > 0);

请注意,在这两个版本中,至少有一个expected_a,但可能还有更多,这与您的set 版本一致。

【讨论】:

  • 但是count不是vector的成员
  • @Ken 我没有使用std::vector.count,而是std::count,它是为任何类型的迭代器定义的,它的复杂性是线性的,不像std::set是对数的,但这对3无关紧要元素(由于std::set 开销可能会更快)。
【解决方案2】:

您可以使用本地的自定义比较功能进行单元测试:

A expected_a(...);

B b;
auto comparator = [](const auto& lhs, const auto& rhs) { /*comparator code*/};
std::set<A, decltype(comparator)> set_of_a({b.nextA() , b.nextA(), b.nextA()}, comparator);

EXPECT_TRUE(set_of_a.count(expected_a) == 1);

【讨论】:

    【解决方案3】:

    GoogleMock 为您提供UnorderedElementsAre and UnorderedElementsAreArray

    std::vector<A> expected {expectedA1, expectedA2};
    std::vector<A> uut {b.nextA(), b.nextA()};
    EXPECT_THAT(uut, ::testing::UnorderedElementsAreArray(expected));
    EXPECT_THAT(uut, ::testing::UnorderedElementsAre(expectedA1, expectedA2));
    

    它将测试所有元素是否以任何顺序在提供的容器中。


    如果您只需要检查集合中的单个元素,那么Contains() 匹配器也存在:

    std::vector<A> uut {b.nextA(), b.nextA()};
    EXPECT_THAT(uut, ::testing::Contains(expected_a));
    

    【讨论】:

      猜你喜欢
      • 2019-04-24
      • 2017-12-30
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 2018-12-01
      • 1970-01-01
      • 2011-04-24
      相关资源
      最近更新 更多