gpt4 book ai didi

c++ - Iceberg 类和 Google 单元测试

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:02:46 24 4
gpt4 key购买 nike

我正在经历对现有代码进行单元测试的过程,该代码在编写时并未考虑单元测试。

有几个类的结构是这样的:

class Texture
{
public:
friend class Model;
private:
void Load( int a, int b);
void Update(int a, int b);
void Use(int a, int b);
}

class Material
{
public:
friend class Model;
private:
void Load(int a);
void Update(int a);
void Use(int a);
}

class Mesh
{
public:
friend class Model;
private:
void Load(int a, int b, int c);
void Update(int a, int b, int c);
void Use(int a, int b, int c);
}


class Model
{
public:

void Load(); // call all the individual Load()
void Use(); // call all the individual Use()
}

它们保持私有(private)的原因是因为它的设计方式只有模型类才能调用它们,因此是 friend 。

[在实际代码中有一个 Attorney-Client 习惯用法,它限制了 Model 对这些类的访问,但我将其排除在代码片段之外]

现在我正在尝试对这些类进行单元测试。在弄清楚如何测试这些私有(private)函数时,我遇到了 Iceberg Class 的术语。我觉得上面的类(class)在某种程度上是有罪的。

大多数涉及该主题的文章还提到,如果需要测试一个私有(private)函数,这主要意味着该类过度了,这些函数最好放在另一个独立的类中,让它们保持公共(public)状态。

所以现在,我不确定这是一个糟糕的代码设计,我应该重新设计它们以使单元测试更容易,还是我只是继续进行单元测试。

想听听大家的意见

最佳答案

为了使这段代码可测试,我将引入三个纯虚拟接口(interface)(ITextureIMeshIMaterial)并添加一个免费的创建此类接口(interface)(例如 getTexture)的方法,该接口(interface)将返回类型为 ITexture 的 smart_ptr。然后在 cpp 文件中实现 get[...] 方法并在生产代码中使用它来创建 Model 对象。在单元测试中,我会为每个接口(interface)类创建一个模拟,并对注入(inject)的模拟设置适当的期望(例如,使用 gmock 或编写您自己的模拟)。

Mesh 示例,头文件 IMesh.hpp:

class IMesh {
public:
virtual ~IMesh() = default;
virtual void Load(int a, int b, int c) = 0;
virtual void Update(int a, int b, int c) = 0;
virtual void Use(int a, int b, int c) = 0;
};
std::unique_ptr<MeshI> getMesh(/*whatever is needed to create mesh*/);

实现文件,MeshImpl.cpp:

#include "IMesh.hpp";

class Mesh : public IMesh {
public:
Mesh(/*some dependency injection here as well if needed*/);
void Load(int a, int b, int c) override;
void Update(int a, int b, int c) override;
void Use(int a, int b, int c) override;
};
Mesh::Mesh(/*[...]*/) {/*[...]*/}
void Mesh:Load(int a, int b, int c) {/*[...]*/}
void Mesh:Update(int a, int b, int c) {/*[...]*/}
void Mesh:Use(int a, int b, int c) {/*[...]*/}

依赖注入(inject):

Model model{getMesh(), getTexture(), getMaterial()};

通过这种方法可以实现:

  1. 更好的解耦——友元是一种非常强大的耦合机制,而依赖纯虚拟接口(interface)是一种常见的方法)
  2. 更好的可测试性 - 不仅针对 Model 类 - 因为接口(interface)中的所有方法都必须是 public 以便 Model 类使用它,您现在可以分别测试每个接口(interface)
  3. 更好的封装:只能通过 getter 方法创建所需的类 - 用户无法访问实现,隐藏所有私有(private)内容。
  4. 更好的可扩展性:现在用户可以提供 IMesh 的不同实现,并在需要时将其注入(inject)模型。

有关 DI 技术的更多详细信息,请参阅 this question

关于c++ - Iceberg 类和 Google 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56536150/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com