在单元测试中,单个游戏不能调用Game构造函数

本文关键字:不能 调用 Game 构造函数 游戏 单个 单元测试 | 更新日期: 2023-09-27 18:11:06

我正在创建一个MonoGame项目,并希望针对现有代码创建单元测试。我创建了一个测试项目,并从GameLopp类(我对项目附带的Game1.cs类的重命名)的简单测试开始。我创建了一个基本的"安装成功"测试,以确保构造函数的构建没有问题:

    public GameLoopTest()
    {
        using (GameLoop game = new GameLoop())
        { game.Run(); }
    }
    public void Dispose()
    {
        _gameloop = null;
    }
    [Fact]
    public void GameLoop_Setup_Suceeds()
    {
        this.Should().NotBeNull();
    }

让我非常困惑的是,测试中的构造函数抛出了一个NullReference异常。如果我在调试模式下执行测试,我会得到一个更详细的异常,告诉我无法找到GraphicsDeviceManager。我四处搜索,但我还没能想出错误发生的原因或如何解决。

我在这个类中没有很多代码,但是我不想让单元测试没有发现这么重要的东西。

在单元测试中,单个游戏不能调用Game构造函数

看看Game类在MonoGame中的实现。

https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Game.cs

在构造函数中,它创建了一个GameServiceContainer,然后在GraphicsDevice getter中使用它来获取一个IGraphicsDeviceService。

为了使事情变得更困难,GraphicsDeviceManager在它的构造函数中使用Game类,并将自己作为服务添加到服务容器中,从而在这两个类之间创建紧密耦合。

https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/GraphicsDeviceManager.cs

这对于单元测试来说并不是特别好的设计,但这并不是MonoGame团队的错,因为他们只是重新实现了微软XNA的行为。

我怀疑你的问题是,你的gamelloop类依赖于一个有效的Game类已经构造,反过来使用内部服务容器。

我的建议是设计你自己的代码,这样它就可以进行单元测试,并尝试将它从呈现代码中解耦,就像你将视图从视图模型中分离出来一样。在最好的情况下,你可能能够使用屏幕截图测试,以确认正确渲染的东西,如果你真的很热衷。