"Niektórzy ludzie, kiedy napotkają problem, myślą: 'Wiem, użyję wyrażeń regularnych'.
I teraz mają dwa problemy."

Jamie Zawinski

czwartek, 25 listopada 2010

Dynamics AX: Pozbycie się komunikatów w testach jednostkowych

Kto kiedyś pisał testy jednostkowe (unit test) w X++ lub został postawiony przed takim faktem, natknął się lub natknie na uporczywe komunikaty - jeśli w testowanym kodzie takie wystąpią. Załóżmy teoretycznie, że testujemy kod w stylu:

while(condition ...)
{
 if (Box::YesNo( arguments ...))
 {
  // action
 }
}


Z odsieczą przychodzi modyfikacja klasy Box będącej odpowiedzialną za wyświetlanie komunikatów maści wszelakiej. Poniżej kod ze zmodyfikowaną metodą yesNo:

public client static DialogButton yesNo(
    str             _text,
    DialogButton    _defaultButton,
    str             _title          = "@SYS11132",
    str             _bottomText     = '')
{
    Container con;
    str retCon;

    if (clientKind() == ClientType::COMObject)
        return _defaultButton;


    // modyfikacja mająca na celu usprawnienie testów jednostkowych
    if (global::hasSecuritykeyAccess(securitykeynum(SysDevelopment), AccessType::View))
    {
        con = xSession::xppCallStack();
        retCon = conpeek(con, conlen(con) - 1);
        if (strscan(retCon, "SysTest", 1, strlen(retCon)))
        {
            return _defaultButton;
        }
    }

    return  new DialogBox(DialogBoxType::YesNoBox,
                          _text,
                          _title,
                          _bottomText,
                          _defaultButton).retval();
}

Jak widać istnieje tutaj zabezpieczenie dla środowiska produkcyjnego. Kod nie powinien wykonać się wtedy kiedy użytkownik nie ma uprawnień do modyfikacji programistycznych.

Powyższa modyfikacja to jedynie propozycja rozwiązania problemu. Ambitniejsi mogą pokusić się o próbę implementacji dynamicznego ustalenia, który przycisk ma być symulowany w testach.

W Dynamics AX 2009 Microsoft wprowadził podobny mechanizm na potrzeby rejestratora zadań (SysTaskRecorder), na którym i w tym przypadku można się wzorować:
if( SysTaskRecorderEventManager::parmRecording() )
        return SysTaskRecorderGlobal::handleDialogButton(DialogBoxType::YesNoBox, _text, _title, _bottomText, _defaultButton);

Brak komentarzy:

Prześlij komentarz