C++:如何使用Google Test在单元测试中模拟不同的时区

5
我正在使用Google测试和C++进行单元测试。在我们公司的代码中,我们仍然存在一个问题,即系统数据类型(例如CTime)使用实际系统的时区(我们与生产代码中的使用方式相同)。为了进行单元测试,我们希望模拟不同的时区,因为我们遇到了许多问题。
我已经花费数小时研究其他人如何解决此问题,因为其他公司肯定也会遇到这个问题:) 但我没有找到解决方案。我的想法是这样的:CTime本身将时间保存为UTC,并按需转换为本地时间。我假设所有这些函数都需要GetTimeZoneInformation()功能,该功能在timezonapi.h中声明。
WINBASEAPI
_Success_(return != TIME_ZONE_ID_INVALID)
DWORD
WINAPI
GetTimeZoneInformation(_Out_ LPTIME_ZONE_INFORMATION lpTimeZoneInformation);

所以解决方案可能是通过一个定制的函数来替换GetTimeZoneInformation()功能,然后返回一个对象,我可以随时更改。但我不知道如何做到这一点,也不知道这是否有效,因为它可能只在应用程序启动时调用此函数一次。
有人知道如何处理这个问题吗?我不想改变任何行为,我只想能够设置自己的时区,而不破坏任何时间计算机制。最好的方法是如果我可以在不改变生产代码的情况下模拟这些调用。
问题是这个程序非常庞大、古老,而且...尽可能少地更改总是最好的 :)
如果我没有找到已经存在的解决我的问题的帖子,那么我很抱歉,因为我要么没有找到它,要么我没有意识到这可以帮助我。

1
看起来你想让我们为你编写一些代码。虽然很多用户愿意帮助有困难的程序员编写代码,但他们通常只会在发帖者已经尝试过自己解决问题时才提供帮助。展示这种努力的好方法是包括你已经编写的代码、示例输入(如果有的话)、期望输出以及实际得到的输出(控制台输出、跟踪等)。提供的细节越多,你可能会收到更多的答案。请查看[FAQ]和[ask]。 - marco.m
1个回答

1
正如您在问题中提到的,模拟是解决此问题的好方法。
我所知道的最快、最简单的方法是将您想要测试的所有方法包装在一个新类中,该类实现了“策略”设计模式:
它可以在真实实现和模拟之间切换,一旦您将逻辑设置为模拟,它将返回模拟值。
默认情况下,应将其设置为真实实现。
使用“int Foo()”的简单示例:
    Class Strategy{
            int Foo() = o
    }

    Class StrategyImplementation
    {
    private:
            Strategy* logic;
    public:
            void SetLogic(Strategy* newLogic){logic=newLogic)}
            int Foo(){return logic->Foo()}
    }

    Class mock : public Strategy{
    public:
            SetValue(int value){this.value = value}
            int Foo(){return value}
    private:
            int value;
        }

    Class Implementation  : public Strategy{
        int Foo(){ here_you_call_the_method_you_want_to_test }
    }

所有需要做的就是将每个GetTimeZoneInformation的调用更改为新策略,最简单的方法是使用“单例”设计模式。 这并不具有很高的风险,您需要做的更改是将调用从'Foo()'更改为'StrategyImplementation :: GetInstance()。Foo()'。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接