You Are Here:

Community: Wiki

This page was last modified on 17 March 2009, at 03:31.

Creating Symbian C++ Unit Tests for Active Objects

From Forum Nokia Wiki

Contents

Introduction

One of the most important features of Symbian C++ is the use of Active Objects to deal with asynchronous services. Almost all asynchronous requests are made by the use of Active Objects, therefore, this article explains how you can make unit tests for these objects.

To make this possible, it is necessary to create a nested wait loop in the current Active Scheduler, that way you can test Active Objects in the scope of one test method. In this particular case, it is used the CActiveSchedulerWait class (See CS000982_-_Using_CActiveSchedulerWait).

Pre-Requisites

Please configure one project with support to Unit Tests as explained in: How to create a Symbian C++ project with Unit Tests

Step 1: Creating your Active Object Class

Create an Active Object Class using the Carbide C++ Wizard. This wizard will create a timer class. To make possible check the results of the asynchronous request, let’s create an observer class (MAOTestObserver) that will be implemented by our test class. Also, the constructor of our CActive class (CAOTestClass) will receive as argument a MAOTestObserver, as showed in the following code:

AOTestClass.h

class MAOTestObserver
{
public:
virtual void CallCompleted( int i ) = 0;
};
 
class CAOTestClass : public CActive
{
public:
// Cancel and destroy
~CAOTestClass();
 
// Two-phased constructor.
static CAOTestClass* NewL(MAOTestObserver* aObserver);
 
// Two-phased constructor.
static CAOTestClass* NewLC(MAOTestObserver* aOobserver);
 
public:
// New functions
// Function for making the initial request
void StartL(TTimeIntervalMicroSeconds32 aDelay);
 
private:
// C++ constructor
CAOTestClass(MAOTestObserver* aObserver);
 
// Second-phase constructor
void ConstructL();
 
private:
// From CActive
// Handle completion
void RunL();
 
// How to cancel me
void DoCancel();
 
// Override to handle leaves from RunL(). Default implementation causes
// the active scheduler to panic.
TInt RunError(TInt aError);
 
private:
enum TAOTestClassState
{
EUninitialized, // Uninitialized
EInitialized, // Initalized
EError
// Error condition
};
 
private:
TInt iState; // State of the active object
RTimer iTimer; // Provides async timing service
MAOTestObserver* iObserver;
 
};

And, let’s make a little change in the RunL implementation. After the asynchronous request is completed, the callback of the observer will be called, as follow:

AOTestClass.cpp

void CAOTestClass::RunL()
{
if (iState == EUninitialized)
{
// Do something the first time RunL() is called
iState = EInitialized;
}
else if (iState != EError)
{
// Do something
}
iObserver->CallCompleted( 2 );
}

Now our Active Object is ready to be tested.

Step 2: Testing your Active Object

Now, it is necessary to create the nested loop in our test suite. For that, let’s use the CActiveSchedulerWait class. Also, our test class (CTest) will implement the MAOTestObserver class.

To test the Active Object, in the CTest class it is called the StartL() method and after that is called the Start() method from the CActiveSchedulerWait object. The execution will be stopped in the Start() call until the AsyncStop() method of the CActiveSchedulerWait object is called. Therefore, in the implementation of the callback of the MAOTestObserver is called the AsyncStop() method. Also, in this method, it is received an integer for the Active Object to be tested.

After the AsyncStop() call, the execution is continued after the Start() call and the ASSERT call is executed, therefore, testing the Active Object. The following code shows this implementation.

TestSource.cpp

#include "TestHeader.h"
#include "TestDriver.h"
#include "Logger.h"
#include <avkon.hrh>
#include <aknmessagequerydialog.h>
#include <aknnotewrappers.h>
void CTest::setUp()
{
iWait = new (ELeave) CActiveSchedulerWait;
iMyClass = CDoStuffClass::NewL();
iMyAOClass = CAOTestClass::NewL(this);
}
 
void CTest::tearDown()
{
if( iMyClass )
{
delete iMyClass;
}
if( iMyAOClass )
{
delete iMyAOClass;
}
if( iWait )
{
delete iWait;
}
}
 
void CTest::testFirstMethod()
{
TInt i = 2;
TInt j = iMyClass->MethodToTest();
TS_ASSERT_EQUALS( i, j);
}
 
void CTest::testFirstMethodAgain()
{
iMyAOClass->StartL(5000000); //Async call: 5 seconds.
iWait->Start(); //wait until the AsyncStop() call
TS_ASSERT_EQUALS( 2, iAsyncResponse );
}
 
void CTest::CallCompleted( int i )
{
iAsyncResponse = i; //Copying the Response
iWait->AsyncStop();
}

NOTE: We are waiting 5 seconds in the nested loop.

After that, compile and run your test case as explained in: How to create a Symbian C++ project with Unit Tests

Example source code

External links

Related Wiki Articles

No related wiki articles found

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fSmallE5fCarbideE5frssE5fgenerationE5ftroubleX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqfntypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qfnZtopicQUqfnTopicZtestingQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZtypeQUqfntypeZWikiContentQ qfnZuserE5ftagQSxtestingX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqfntypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ