我正在将 C++/ WTL项目从 Visual Studio 2005 移植到 VS 2008。项目配置之一是单元测试构建,它定义了预处理器符号 UNIT_TEST。
为了让我的 WTL 类进入我的测试工具,我创建了一个CFakeWindow
存根所有 CWindow 方法的类。然后在我的 stdafx.h 文件中,我在 atlwin.h(它定义了 CWindow 类)的导入下方执行此操作:
#ifdef UNIT_TEST
#include "fakewindow.h"
#define CWindow CFakeWindow
#endif
我的窗口类看起来像这样:
class CAboutDialog :
public CDialogImpl< CAboutDialog, CWindow >
, public CDialogResize< CAboutDialog >
{
// class definition omitted...
};
这在 VS 2005 中效果很好。问题是在 VS 2008 中,来自原始 CWindow 类的方法被调用,而不是 CFakeWindow 类。这当然会导致测试失败,CWindow
因为ATLASSERT(::IsWindow(m_hWnd))
.
当我在调试器中单步执行代码时,我看到 CAboutDialog 类继承自CDialogImpl<CAboutDialog, CFakeWindow>
. 然而,当我在CAboutDialog
(例如EndDialog(code)
)上调用一个方法时,该CWindow
方法被调用了。
这是 VS 2008 中的错误,还是我的条件模板继承技术是 VS 2005 允许但 VS 2008“修复”的可憎?是否有解决方法,或者我是否需要考虑一种不同的技术来对 WTL 类进行单元测试?我真的很喜欢这种技术,因为它让我可以将 WTL 类放入测试工具中,而无需与 WTL 库打交道。
编辑:正如下面对 Conal 的响应中所述,预处理器输出显示我的类是从 CFakeWindow 继承的:
class CAboutDialog :
public CDialogImpl<CAboutDialog, CFakeWindow >
, public CDialogResize< CAboutDialog >
...
如上所述,当我在调试器中单步执行代码时,CAboutDialog 在本地窗口中显示为继承自 CFakeWindow。
编辑 2:根据 Conal 的建议,我逐步完成了反汇编,代码应该调用 CFakeWindow 方法,但实际调用的是 CWindow 方法。
if ( wID == IDCANCEL )
00434898 movzx edx,word ptr [ebp+8]
0043489C cmp edx,2
0043489F jne CAboutDialog::OnCloseCmd+90h (4348B0h)
{
EndDialog( wID ) ;
004348A1 movzx eax,word ptr [ebp+8]
004348A5 push eax
004348A6 mov ecx,dword ptr [ebp-10h]
004348A9 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
}
else
004348AE jmp CAboutDialog::OnCloseCmd+9Ah (4348BAh)
{
EndDialog(IDOK);
004348B0 push 1
004348B2 mov ecx,dword ptr [ebp-10h]
004348B5 call ATL::CDialogImpl<CAboutDialog,ATL::CFakeWindow>::EndDialog (40D102h)
我开始更倾向于 VC++ 2008 调试器中的错误。