C语言 模拟和Win32 API调用

qzlgjiam  于 2023-03-12  发布在  其他
关注(0)|答案(5)|浏览(215)

我目前正在开发的产品是一个用C++编写的Windows服务,并且以后所有新功能都将为其编写单元测试。但这产生了一个有趣的问题(至少对我来说),我们为各种事情执行了大量Win32调用,并相应地执行,因此为了完成单元测试,测试各种输出是很好的,而不仅仅是当前系统状态。
我的问题是模拟Win32调用结果的最佳方法是什么?我考虑了两种不同的方法:
1)将所有使用过的Win32调用放入函数指针中,并将它们传递给使用它们的函数或类(取决于它们被命中的次数),然后使用这些函数或类来获得模拟结果。
2)到处都有很多#ifdef UNITTEST,如果它调用我自己的特殊方法,或者如果没有,就调用普通的方法。
我是不是完全跑题了,还是漏掉了一个基本知识?

vddsk6oq

vddsk6oq1#

我建议将API调用封装到分解良好的接口中。然后您可以使用模拟对象或测试双精度对象来测试您的业务逻辑。您不需要测试Windows API本身,因为数百万工作的Windows应用程序已经完成了这一工作。
如果你不开发硬件,单元测试就不应该涉及硬件访问,它只是测试你的逻辑代码。

3okqufwl

3okqufwl2#

使用Deviare API钩子拦截所有API调用并进行单元测试。

91zkwejq

91zkwejq3#

如果可能,最好在不修改Win32调用的情况下使事件发生。
例如,不要创建自己的CreateFile(因为文件正在使用中而失败),而是使用另一个程序(从单元测试中调用)以独占方式打开该文件,然后运行单元测试。
如果你必须模拟一些win32调用,那么最好围绕你想要进行的Win32调用集创建一个 Package 器库,这样你就不会损害主逻辑的代码读写能力。

6yoyoihd

6yoyoihd4#

关于(2),大多数采用字符串参数的Win32函数已经将它们的公共形式定义为宏,例如来自WinUser.h:

WINUSERAPI
int
WINAPI
MessageBoxA(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);
#ifdef UNICODE
#define MessageBox  MessageBoxW
#else
#define MessageBox  MessageBoxA
#endif // !UNICODE

你当然可以在你的项目中添加一个头文件来重新定义你想要模拟的API函数:

#ifdef UNITTEST
#undef MessageBox
#define MessageBox UnitTestMessageBox
#endif

通过重新定义名称,可以避免在源代码中分散大量的条件编译。

ar5n3qh5

ar5n3qh55#

最后我实际上采取了更多的C#风格的方法,并创建了允许我消除我想要使用的Win32调用的接口。
例如,我有一个名为IRegistryOperations的函数,它包含RegOpenKeyRegQueryValueExRegNotifyChange和其他几个我正在使用的函数,一个默认的函数只是在构造函数中创建的,但我也有一个接受接口的构造函数,这样我就可以模拟可疑的值,等等。
(Not当然,如果回答我自己问题是不礼貌的)

相关问题