【问题标题】:TYPED_TEST for a class template <typename T, size_t size>TYPED_TEST 用于类模板 <typename T, size_t size>
【发布时间】:2021-09-15 23:08:53
【问题描述】:

我正在尝试为名为 Client 的模板类编写单元测试。无法成功编译 unitTests 代码。不确定如何在单元测试中同时传递 class / typename Tsize_t size 参数。如果您希望在本地机器上编译并查看问题,我已经创建了一个 git repo git clone https://github.com/BhanuKiranChaluvadi/gtest-minimal-example.git

#pragma once

#include <array>

namespace inputs
{
    template <typename T, size_t size>
    class IClient
    {
    public:
        using ClientType = std::array<T, size>;
        virtual const ClientType &getID() const = 0;
        virtual bool isID(const ClientType &anotherID) const = 0;
    };

    template <typename T, size_t size>
    class Client : public IClient<T, size>
    {
    public:
        using ClientT = std::array<T, size>;

        Client(const ClientT &ID) : ID(ID) {}
        Client(const ClientT &&ID) : ID(std::move(ID)) {}

        inline const ClientT &getID() const override { return ID; }
        inline bool isID(const ClientT &anotherID) const override { return ID == anotherID; }

        inline bool operator==(const Client &anotherClient) { return ID == anotherClient.getID(); }

    private:
        ClientT ID;
    };

} // namespace inputs

这就是我的谷歌测试的样子

#include "gtest/gtest.h"
#include <type_traits>
#include "client.hpp"
#include <memory>
#include <utility>
#include <tuple>

using namespace inputs;

namespace inputs_test
{

    template <class T, size_t size>
    class ClientTest : public testing::Test
    {
    };

    using testing::Types;

    // The list of types we want to test.
    typedef Types<std::pair<int8_t, std::integral_constant<std::size_t, 16>>,
                                std::pair<uint8_t, std::integral_constant<std::size_t, 24>>>
            Implementations;

    TYPED_TEST_CASE(ClientTest, Implementations);

    TYPED_TEST(ClientTest, shouldReturnSetID)
    {
        typename TypeParam::first_type data_type;
        typename TypeParam::second_type size;
        // static constexpr std::size_t n = TypeParam::value;
        EXPECT_TRUE(true);
    }

} // namespace inputs_test

模板化的客户端类应为&lt;int8_t, 16&gt;&lt;uint8_t, 24&gt;。我不确定如何传递size_t 模板化参数。

test/googletest-src/googletest/include/gtest/gtest-typed-test.h:174:38: error: wrong number of template arguments (1, should be 2)
  174 |     typedef CaseName<gtest_TypeParam_> TestFixture; \

【问题讨论】:

  • 你看过TYPED_TEST宏解析到什么吗?另外,你能提供一个minimal reproducible example吗?再加上它产生的输出,这样人们就可以将错误消息与导致它的代码相匹配。顺便说一句:我认为重要的区别是您使用的是非类型模板参数(MCVE 将验证这一点)。如果我猜对了,请考虑将其添加到您的搜索和问题标题中。
  • @UlrichEckhardt 这是我正在使用的确切代码,只需在此处复制粘贴即可。我正在使用Ubuntu 20.04g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0,我从最新的大师那里编译了谷歌测试
  • 我不怀疑它是从您的实际代码中复制而来的。但是,它仍然不完整,仍然分为两个文件,并且包含显然不需要的代码。确保我可以将其复制粘贴到文件中并查看完全相同的问题。
  • 嗨@UlrichEckhardt 我在问题的描述中添加了一个github repo。您可以克隆并执行 cmake .and make。

标签: c++ unit-testing templates c++14 googletest


【解决方案1】:

一种可能的解决方案是编写一个ClientTest 类,它将std::tuple(或std::pair)作为单个模板参数,并将其拆分为两个模板参数Tsize,再次使用std::tuple_element。然后它将Client&lt;T, size&gt; 实例化为类成员。然后可以使用它来执行所需的测试:

namespace inputs_test {
  template <typename Tup>
  class ClientTest: public testing::Test {
    using T = typename std::tuple_element_t<0, Tup>;
    static constexpr std::size_t size = std::tuple_element_t<1, Tup>::value;
    using ClientT = typename inputs::Client<T, size>::ClientT;

    protected:
      ClientTest() noexcept 
        : id{new ClientT{}}, client{new inputs::Client<T, size>{*id}} {
        return;
      }

      ~ClientTest() noexcept {
        delete id;
        delete client;
      }

      ClientT* id;
      inputs::Client<T, size>* client;
  };

  typedef testing::Types<std::tuple<std::int8_t,  std::integral_constant<std::size_t, 16>>,
                         std::tuple<std::uint8_t, std::integral_constant<std::size_t, 24>>>
          Implementations;

  TYPED_TEST_CASE(ClientTest, Implementations);

  TYPED_TEST(ClientTest, shouldReturnSetID) {
    EXPECT_EQ(this->client->getID(), *this->id);
  }
}

【讨论】:

  • 嗨@2b-t,我尝试编译上面的代码,但不幸的是,由于一些不推荐使用的函数gmock-matchers.h:432:67: error: implicitly-declared ‘testing::internal::EndsWithMatcher&lt;std::__cxx11::basic_string&lt;wchar_t&gt; &gt;::EndsWithMatcher(const testing::internal::EndsWithMatcher&lt;std::__cxx11::basic_string&lt;wchar_t&gt; &gt;&amp;)’ is deprecated [-Werror=deprecated-copy],出现了编译错误。如果你想自己编译,请参考问题中的github页面。
  • @BhanuKiran 它在带有sudo apt-get install libgtest-dev 和 GCC 7.5.0 的 Ubuntu 18.04 上编译。它说什么?我没有关注 C++ 标准。也许与此有关。
  • @BhanuKiran 我安装了几个 g++ 的替代品。我将尝试切换并克隆您的存储库。让我们看看...
  • 嗨@2b-t,我在 debian10 上尝试使用 gcc (Debian 8.3.0-6) 8.3.0 编译成功但是在 Ubuntu 20.04 和 gcc (Ubuntu 9.3.0-17ubuntu1~20.04 ) 9.3.0 失败
  • @BhanuKiran 我刚刚玩过几个版本。它可以很好地与您的 Github 项目和 g++7.5.0 和 9.2.1 以及 clang 12.0.1 一起编译。在其他 g++ 版本中,添加编译标志 -Wno-error=deprecated-copy 以忽略弃用警告。实际上,这取决于编译库的内容。如果我用7.5.0 编译库,然后使用10.3.011.1.0,它无论如何都可以工作。我认为这是googletest 库的问题,而不是我的代码本身的问题。
猜你喜欢
  • 1970-01-01
  • 2013-04-05
  • 2021-10-29
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多