Frage

Ich bin im Begriff, eine C portieren ++ / WTL Projekt von Visual Studio 2005 auf VS 2008 . eine der Projektkonfigurationen ist eine Einheit-Test bauen, die das Präprozessorsymbol UNIT_TEST.

definiert

Um meine WTL Klassen in meinem Test-Harnisch zu bekommen, habe ich eine CFakeWindow Klasse, die alle CWindow Methoden Stümpfe. Dann in meiner stdafx.h Datei, sehe ich das direkt unter dem Import von atlwin.h (die die CWindow Klasse definiert):

#ifdef UNIT_TEST
#include "fakewindow.h"
#define CWindow CFakeWindow
#endif

Meine Fensterklassen dann wie folgt aussehen:

class CAboutDialog : 
    public CDialogImpl< CAboutDialog, CWindow > 
    , public CDialogResize< CAboutDialog >
{
// class definition omitted...
};

Dies funktioniert gut in VS 2005. Das Problem ist, dass die Methoden von der ursprünglichen CWindow Klasse in VS 2008, genannt zu werden, statt der CFakeWindow Klasse. Dies verursacht natürlich die Tests fehlschlagen, weil CWindow mit ATLASSERT(::IsWindow(m_hWnd)) bestreut wird.

Wenn ich durch den Code im Debugger Schritt, ich sehe, dass die CAboutDialog Klasse von CDialogImpl<CAboutDialog, CFakeWindow> erbt. Doch wenn ich eine Methode auf CAboutDialog nennen (z EndDialog(code)), die CWindow Methode aufgerufen zu werden.

Ist das ein Fehler in VS 2008, oder war meine bedingte Vorlage Vererbung Technik ein Gräuel, dass VS 2005 erlaubt, aber VS 2008 „fest“? Gibt es eine Behelfslösung, oder brauche ich eine andere Technik, um Unit-Test WTL Klassen zu beachten? Ich mag diese Technik wirklich, weil es mir WTL-Klassen in einer Testumgebung optimal nutzen können, ohne sich um die WTL Bibliothek Ausmisten.

Bearbeiten : Wie in der Antwort auf Conal erwähnt, unterhalb der Präprozessorausgabe zeigt, dass meine Klasse von CFakeWindow erbt:

class CAboutDialog :
    public CDialogImpl<CAboutDialog, CFakeWindow >
    , public CDialogResize< CAboutDialog >
    ...

Und wie oben erwähnt, als ich durch den Code im Debugger Schritt wird CAboutDialog im Lokalfenster gezeigt, wie von CFakeWindow vererben.

Edit 2 . Wie pro Conal Rat, ich durch die Demontage trat, und der Code ist angeblich die CFakeWindow Methode aufrufen, aber die CWindow Methode ist das, was tatsächlich aufgerufen wird,

        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) 

Ich fange mehr zu einem Fehler in den VC ++ 2008 Debugger zu lehnen.

War es hilfreich?

Lösung

Dies könnte ein klareres Art des Umgangs es sein:

#ifdef UNIT_TEST
#include "fakewindow.h"
#define TWindow CFakeWindow
#else
#define TWindow CWindow
#endif

Vielleicht gibt es einen Fall, in dem die neu zu definieren ist nicht durch die vorkompilierte Header bekommen. Wenn ja, wird eine solche Problem fangen.

Andere Tipps

Ich denke, das ist eine lange gedreht, aber ist es möglich, dass vorkompilierte Header Verwüstung mit Ihrem Build spielen? Versuchen Sie drehen Sie sie in Ihrem Projekt ab (wenn sie es auf) und machen Sie einen bereinigter Build, um zu sehen, wenn Sie eine bessere Verhalten bekommen.

Haben Sie sich die Präprozessorausgabe zu bestätigen, dass der Hack in der Tat ist das, was Sie denken? Mit Hilfe der Präprozessor Klassen umbenennen, die Teil einer Vorlagenbibliothek sind, ist voller Gefahren. Prüfen Sie auch, dass die Unterschrift von jeder und jede Methode in Ihrem CFakeWindow entspricht genau CWindow.

VS2008 gibt es schon seit geraumer Zeit jetzt, also würde ich nicht einen Compiler Fehler in Betracht ziehen, bis Sie zuerst alle anderen Möglichkeiten ausgeschlossen haben.

Versuchen Sie so etwas wie:

class CAboutDialog :
    public CDialogImpl<CAboutDialog, FAKE_CWindow_MACRO >

So können Sie aufhören können versuchen, den Prä-Prozessor zu verwenden, um System-Header-Dateien neu zu schreiben, und es für Ihren eigenen Code verwenden.

Ja, ich weiß, Sie müssen den Code „Refactoring“, aber es ist eine Suche-und-Ersetzen-Job.

Ihre aktuelle Technik ist so etwas wie ein Hack, weil es eine unberechtigte Annahme macht: dass keine Quelldatei jeden Header von ATL # include wird, die auf einer einheitliche Definition von CWindow beruht. Dies ist wahrscheinlich nicht als Code-Änderungen im Laufe der Zeit stabil.

  

Dann in meiner stdafx.h-Datei, kann ich diese

AFAIK, stdafx.h ist eine vorkompilierte Header standardmäßig. Also, wenn Sie UNIT_TEST Makro definieren, ist es nicht vorkompilierte Datei beeinflussen, die noch als Template-Argument CWindow hat.

Ich sehe die Bibliothek Symbole im Namensraum ATL sind. Ist das vielleicht Ihr Makro Betrügerei Abwerfen?

Im Allgemeinen würde ich nicht auf einem Debugger zählen Vorlage instantiations perfekt zu melden. Zu viele seltsame Optimierungen erforderlich sind, um passieren, auch in Debug baut.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top