Re: [TFUI] The MVP pattern and loose coupling between view/presenter and presenter/model

Anthony Williams <anthony_w.geo-/[email protected]> Mon, 19 Sep 2005 16:25:37 +0100
Newsgroups gmane.comp.programming.test-first-user-interfaces
Message-ID <[email protected]>
"Rob Park" <[email protected]> writes:

> Where do you plug in your tests in this model?
> .rob.
>
>>
>>You could think of this as Model (Backend classes) View (GUI class) 
>>Presenter
>>(Collaborator), but I think that the way I work has the boundaries at a
>>different level. There's none of this mapping between UI events and 
>>presenter
>>methods --- the GUI class handles UI events, and only requests business 
>>info
>>and external user interaction from the collaborator; a typical dialog might
>>only invoke two calls on the collaborator during its entire existence --- 
>>once
>>at the beginning to request current state information, and once at the end 
>>to
>>set new state.

I instantiate a GUI-facing class in a test, with a mock collaborator. My tests
will typically simulate user interaction with the GUI, and verify that the GUI
is correctly updated. Likewise I will have tests that verify the interactions
with the collaborator. This is the TFUI list, after all.

Here's an extract from the tests on one of my projects:

class TestGenerateLicenceKeyDialog:
    public LicenceGenerator // self-shunt for mocking collaborator
    //...
{
    GeneratedLicenceKeyDialog dlg;

    // Setup happens in the constructor
    TestGenerateLicenceKeyDialog(/*...*/):
        dlg(*this)
        //...
    {
        dlg.Create(NULL);
    }

    // and TearDown in the destructor
    ~TestGenerateLicenceKeyDialog()
    {
        dlg.DestroyWindow();
    }

    // ...

    void testSelectingUnlimitedLicenceDisablesExpiryDate()
    {
        // interact with GUI
        simulateRadioButtonSelection(dlg,IDC_UNLIMITED_LICENCE);

        // check result
        TEST_ASSERT(!isDialogItemEnabled(dlg,IDC_EXPIRY_DATE_CAPTION));
        TEST_ASSERT(!isDialogItemEnabled(dlg,IDC_EXPIRY_DATE));
    }

    // ...

    // Use self-shunt for mocking the collaborator
    std::string generateLicenceKey(std::string const&hostKey,GeneratedLicenceType licenceType,SYSTEMTIME const& expiryDate,unsigned licenceCount,
                                   std::string const& product,
                                   unsigned majorVersion,
                                   unsigned minorVersion)
    {
        suppliedExpiryDate=expiryDate;
        suppliedLicenceType=licenceType;
        suppliedHostKey=hostKey;
        suppliedLicenceCount=licenceCount;
        suppliedProduct=product;
        suppliedMajorVersion=majorVersion;
        suppliedMinorVersion=minorVersion;
        return licenceKey;
    }

    void testClickingOkGeneratesLicence()
    {
        std::string const hostKey="my host key";
        SYSTEMTIME const expiryDate={
                    2029, // year
                    5, // month
                    0, // dummy
                    27, // day
                    22, // hour
                    59, // minute
                    17 // second
        };
        unsigned const licenceCount=5;
        unsigned const majorVersion=3;
        unsigned const minorVersion=9;

        // set up GUI state
        setDlgItemText(dlg,IDC_HOST_KEY,hostKey);
        simulateRadioButtonSelection(dlg,IDC_TIME_LIMITED_LICENCE);
        dlg.GetDlgItem(IDC_EXPIRY_DATE).SendMessage(DTM_SETSYSTEMTIME,GDT_VALID,(LPARAM)&expiryDate);
        dlg.SetDlgItemInt(IDC_LICENCE_COUNT,licenceCount,false);
        dlg.SetDlgItemInt(IDC_MAJOR_VERSION,majorVersion,false);
        dlg.SetDlgItemInt(IDC_MINOR_VERSION,minorVersion,false);

        // here's the action we're testing
        simulateButtonClick(dlg,IDOK);

        // check results.
        TEST_ASSERT_EQUALS(suppliedHostKey,hostKey);
        TEST_ASSERT_EQUALS(suppliedLicenceType,timeLimitedLicence);
        TEST_ASSERT_EQUALS(suppliedExpiryDate,expiryDate);
        TEST_ASSERT_EQUALS(suppliedLicenceCount,licenceCount);
        TEST_ASSERT_EQUALS(suppliedProduct,applicationName);
        TEST_ASSERT_EQUALS(suppliedMajorVersion,majorVersion);
        TEST_ASSERT_EQUALS(suppliedMinorVersion,minorVersion);
        TEST_ASSERT_EQUALS(getDialogItemString(dlg,IDC_LICENCE_KEY),licenceKey);
    }
    
};

The collaborator is just a normal class, so is easy to test.

Anthony
-- 
Anthony Williams
Software Developer
Just Software Solutions Ltd
http://www.justsoftwaresolutions.co.uk



------------------------ Yahoo! Groups Sponsor --------------------~--> 
Most low income households are not online. Help bridge the digital divide today!
http://us.click.yahoo.com/cd_AJB/QnQLAA/TtwFAA/nhFolB/TM
--------------------------------------------------------------------~-> 

To unsubscribe, email:
TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/TestFirstUserInterfaces/

<*> To unsubscribe from this group, send an email to:
    TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/