【问题标题】:How to handle different asserts based on template types如何根据模板类型处理不同的断言
【发布时间】:2022-01-19 11:51:45
【问题描述】:

目前,我正在使用 TYPED_TEST 为通用类(模板)编写一个带有谷歌测试的单元测试。我必须解决的问题是我的类根据数据类型产生不同的结果。测试不能考虑数据类型。而且我不想为每种数据类型编写测试。

好的,让我在一个非常简单的上下文中解释这一点。 例如我们在 Calculator.h 中有一个计算器类:

#pragma once

template <typename T>
class Calculator
{
public:
    Calculator()
        : _value(0)
    {
    }


    T Add(T valA, T valB)
    {
        _value = valA + valB;
        return _value;
    }

    T Add(T val)
    {
        _value += val;
        return _value;
    }

private:
    T _value;
};

这是我的测试:

#include <gtest/gtest.h>
#include "Calculator.h"

template <typename T>
class CalculatorTestFixture : public testing::Test
{
public:
    void SetUp() override
    {

    }

    void TearDown() override
    {

    }

    Calculator<T> _calculator;
};


typedef testing::Types<int, float> TypesToTest;

TYPED_TEST_CASE(CalculatorTestFixture, TypesToTest);

TYPED_TEST(CalculatorTestFixture, TestTypes)
{
    // ARRANGE
    TypeParam val1 = (TypeParam)1.8;
    TypeParam val2 = (TypeParam)1.2;
    TypeParam testVal = (TypeParam)0;
    TypeParam expectedVal = (TypeParam)3.0;

    // ACT
    testVal = this->_calculator.Add(val1, val2);
     
    // ASSERT
    ASSERT_EQ(expectedVal, testVal);
}

数据类型 int 的测试将失败,因为该类计算 1+1=2,而这正是我对该数据类型的预期。

是否有像参数测试这样的好解决方案,我可以在其中额外定义数据类型的预期输出值,还是应该为每种支持的数据类型编写测试?

【问题讨论】:

  • "测试不能考虑数据类型。"似乎与您的要求相矛盾
  • 你的期望是错误的,而不是(TypeParam)3.0,它应该是(((TypeParam)1.8) + ((TypeParam)1.2))或简单的val1 + val2。
  • 你仍然可以创建重载int some_value(Tag&lt;int&gt;) {return 2;} double some_value(Tag&lt;double&gt;) {return 3.;} 并使用类似`TypeParam expectedVal = some_value(Tag{});`。

标签: c++ unit-testing templates googletest


【解决方案1】:

模板专业化对我有用。我将预期值移动到返回预期结果的抽象方法中。通过模板特化,可以解决类型依赖的结果。

#include <gtest/gtest.h>
#include "Calculator.h"

template <typename T>
class CalculatorTestFixture : public testing::Test
{
public:
    void SetUp() override
    {
        _val1 = (T)1.8;
        _val2 = (T)1.2;
    }

    void TearDown() override
    {

    }

    T expectedResult()
    {
        return (T)0;
    }

    Calculator<T> _calculator;
    T _val1;
    T _val2;
};


int CalculatorTestFixture<int>::expectedResult()
{
    return 2;
}

float CalculatorTestFixture<float>::expectedResult()
{
    return 3.0f;
}


typedef testing::Types<int, float> TypesToTest;

TYPED_TEST_CASE(CalculatorTestFixture, TypesToTest);

TYPED_TEST(CalculatorTestFixture, TestTypes)
{
    // ARRANGE
    TypeParam testVal = (TypeParam)0;
    TypeParam expectedVal = this->expectedResult();

    // ACT
    testVal = this->_calculator.Add(this->_val1, this->_val2);
     
    // ASSERT
    ASSERT_EQ(expectedVal, testVal);
}

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 2020-05-16
    • 2021-12-09
    • 2018-06-11
    • 2022-12-31
    • 2022-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多