Archived:Creating Symbian C++ Unit Tests for Active Objects
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 Archived:Using CActiveSchedulerWait).
Please configure one project with support to Unit Tests as explained in: Archived: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:
virtual void CallCompleted( int i ) = 0;
class CAOTestClass : public CActive
// Cancel and destroy
// Two-phased constructor.
static CAOTestClass* NewL(MAOTestObserver* aObserver);
// Two-phased constructor.
static CAOTestClass* NewLC(MAOTestObserver* aOobserver);
// New functions
// Function for making the initial request
void StartL(TTimeIntervalMicroSeconds32 aDelay);
// C++ constructor
// Second-phase constructor
// From CActive
// Handle completion
// How to cancel me
// Override to handle leaves from RunL(). Default implementation causes
// the active scheduler to panic.
TInt RunError(TInt aError);
EUninitialized, // Uninitialized
EInitialized, // Initalized
// Error condition
TInt iState; // State of the active object
RTimer iTimer; // Provides async timing service
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:
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.
iWait = new (ELeave) CActiveSchedulerWait;
iMyClass = CDoStuffClass::NewL();
iMyAOClass = CAOTestClass::NewL(this);
if( iMyClass )
if( iMyAOClass )
if( iWait )
TInt i = 2;
TInt j = iMyClass->MethodToTest();
TS_ASSERT_EQUALS( i, j);
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
NOTE: We are waiting 5 seconds in the nested loop.
After that, compile and run your test case as explained in: Archived:How to create a Symbian C++ project with Unit Tests
Example source code
- The modified application can be found here: MyFirstUnitTestAppAO.zip