我正在编写的库中有以下渲染器 API:
class EXPORT Renderer {
public:
Renderer(const Renderer &) = delete;
Renderer &operator=(const Renderer &) = delete;
virtual ~Renderer();
protected:
Renderer() = default;
public:
[[nodiscard]] static std::unique_ptr<Renderer> create(const RendererDescriptor &descriptor);
[[nodiscard]] virtual std::unique_ptr<SwapChain> createSwapChain(const SwapChainDescriptor &descriptor, const Window &window) = 0;
[[nodiscard]] virtual std::unique_ptr<Buffer> createVertexBuffer(const BufferDescriptor &descriptor, const VertexFormat &format) = 0;
[[nodiscard]] virtual std::unique_ptr<Buffer> createIndexBuffer(const BufferDescriptor &descriptor, Format format) = 0;
[[nodiscard]] virtual std::unique_ptr<Shader> createShaderFromString(const ShaderDescriptor &descriptor, std::string_view source) = 0;
[[nodiscard]] virtual std::unique_ptr<PipelineState> createPipelineState(const PipelineStateDescriptor &descriptor) = 0;
[[nodiscard]] virtual std::unique_ptr<CommandList> createCommandList(const CommandListDescriptor &descriptor) = 0;
[[nodiscard]] virtual std::unique_ptr<Texture> createTexture(const TextureDescriptor &descriptor) = 0;
[[nodiscard]] virtual std::unique_ptr<RenderTarget> createRenderTarget(const RenderTargetDescriptor &descriptor) = 0;
[[nodiscard]] virtual std::unique_ptr<RenderPass> createRenderPass(const RenderPassDescriptor &descriptor) = 0;
};
此渲染器 API 在另一个库中实现,例如 OpenGL 后端:
class GLRenderer final : public Renderer {
public:
explicit GLRenderer(const RendererDescriptor &descriptor);
std::unique_ptr<SwapChain> createSwapChain(const SwapChainDescriptor &descriptor, const Window &window) override;
std::unique_ptr<Buffer> createVertexBuffer(const BufferDescriptor &descriptor, const VertexFormat &format) override;
std::unique_ptr<Buffer> createIndexBuffer(const BufferDescriptor &descriptor, Format format) override;
std::unique_ptr<Shader> createShaderFromString(const ShaderDescriptor &descriptor, std::string_view source) override;
std::unique_ptr<PipelineState> createPipelineState(const PipelineStateDescriptor &descriptor) override;
std::unique_ptr<CommandList> createCommandList(const CommandListDescriptor &descriptor) override;
std::unique_ptr<Texture> createTexture(const TextureDescriptor &descriptor) override;
std::unique_ptr<RenderTarget> createRenderTarget(const RenderTargetDescriptor &descriptor) override;
std::unique_ptr<RenderPass> createRenderPass(const RenderPassDescriptor &descriptor) override;
private:
// private members
};
在
Renderer::create
工厂方法中加载此 OpenGL 后端库,并分配 GLRenderer
然后返回。我应该如何使用 GoogleTest 对该 API 进行单元测试?
根据您在评论中的请求,对于针对其公共接口测试多个给定实现的一方面,我制作了一个带有一个玩具接口和两个玩具实现的小示例。希望这可以为您提供一个继续前进的起点(您可以在编译器资源管理器上看到相同的代码):
#include <memory>
#include <gtest/gtest.h>
class interface {
public:
virtual ~interface()=default;
virtual long tripleNum(long) =0;
};
class impl0 : public interface {
public:
virtual ~impl0()=default;
long tripleNum(long const inp) override {
return inp+inp+inp;
}
};
class impl1 : public interface {
public:
virtual ~impl1()=default;
long tripleNum(long const inp) override {
return inp*3;
}
};
static const std::tuple<std::shared_ptr<impl0>,std::shared_ptr<impl1>> PARAMS{
std::make_shared<impl0>(), std::make_shared<impl1>() };
using TEST_TYPES = ::testing::Types<std::shared_ptr<impl0>,std::shared_ptr<impl1>>;
template <typename T> class ImplTests : public testing::Test
{
protected:
ImplTests() : param(std::static_pointer_cast<interface>(std::get<T>(PARAMS))) {}
std::shared_ptr<interface> param;
};
TYPED_TEST_SUITE(ImplTests, TEST_TYPES);
TYPED_TEST(ImplTests, ensure_that_triple_returns_three_times_the_input) {
EXPECT_EQ(27,this->param->tripleNum(9));
}
int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
当然,有些事情可以用更优雅的方式完成(例如,这里可能不需要shared_ptr
)。无论如何,这个例子应该能说明问题。