Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component ball_testobserver
[Package ball]

Provide an instrumented observer for testing. More...

Namespaces

namespace  ball

Detailed Description

Outline
Purpose:
Provide an instrumented observer for testing.
Classes:
ball::TestObserver instrumented observer for testing
See also:
Component ball_record, Component ball_context, Component ball_observer
Description:
This component provides a concrete implementation of the ball::Observer protocol, ball::TestObserver, that is instrumented for testing systems that use ball::Observer objects.
                   ( ball::TestObserver )
                            |             static numInstances
                            |             ctor
                            |             setVerbose
                            |             id
                            |             lastPublishedContext
                            |             lastPublishedRecord
                            |             numPublishedRecords
                            |             numReleases
                            V
                    ( ball::Observer )
                                          dtor
                                          publish
                                          releaseRecords
ball::TestObserver ascribes to each instance (within a process) a unique integer identifier (accessible via the id method), and each instance keeps a count of the total number of records that it has published (accessible via the numPublishedRecords method). In addition, the test observer maintains a copy of the record and context data from the most recent call to publish; that information is available via the accessors lastPublishedRecord and lastPublishedContext.
Thread Safety:
The ball::TestObserver provides a publish method that is thread-safe, meaning that the test observer may be used to log records from multiple threads. However, the ball::TestObserver accessors lastPublished method and lastPublishedContext provide references to internal data structures (for backwards compatibility) and are therefore not thread-safe.
Verbose Mode:
The publish method, in addition to making a local copy of the published data for future inspection, is capable of printing an appropriate diagnostic message to the ostream held by the test observer instance. By default, this printing is suppressed, but the behavior can be altered by calling the setVerbose method. A call to setVerbose with a non-zero argument (e.g., setVerbose(1)) places the object in verbose mode, which enables diagnostic printing. A subsequent call of setVerbose(0) restores the default "quiet" behavior.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Usage:
The following snippets of code illustrate the basic usage of testing observer objects. The example focuses on the individual features that are useful for testing larger systems (not shown) that use observers derived from ball::Observer.
First create a ball::Record object record and a ball::Context object context. Note that the default values for these objects (or their contained objects) are perfectly suitable for testing purposes, since the testing observer's purpose is simply to report what has been presented to its publish method.
  ball::RecordAttributes attributes;
  ball::UserFields       fieldValues;
  ball::Context          context;

  bslma::Allocator *ga = bslma::Default::globalAllocator(0);
  const bsl::shared_ptr<const ball::Record>
             record(new (*ga) ball::Record(attributes, fieldValues, ga), ga);
Next, create three test observers to1, to2', and to3, each with bsl::cout as the held stream. Note that each instance will be given a unique integer identifier by the constructor.
  assert(0 == ball::TestObserver::numInstances());

  ball::TestObserver to1(&bsl::cout);
  assert(1 == to1.id());
  assert(1 == ball::TestObserver::numInstances());

  ball::TestObserver to2(&bsl::cout);
  assert(2 == to2.id());
  assert(2 == ball::TestObserver::numInstances());

  ball::TestObserver to3(&bsl::cout);
  assert(3 == to3.id());
  assert(3 == ball::TestObserver::numInstances());

  assert(0 == to1.numPublishedRecords());
  assert(0 == to2.numPublishedRecords());
  assert(0 == to3.numPublishedRecords());
Finally, set to1 to "verbose mode" and publish record and context to to1 and also to to2, but not to to3.
  to1.setVerbose(1);
  to1.publish(record, context);
  assert(1 == to1.numPublishedRecords());

  to2.publish(record, context);
  assert(1 == to2.numPublishedRecords());
  assert(0 == to3.numPublishedRecords());
This will produce the following output on stdout:
  Test Observer ID 1 publishing record number 1
  Context: cause = PASSTHROUGH
           count = 1 of an expected 1 total records.
Note that to2 produces no output, although its publish method executed (as verified by the numPublishedRecords method); only to1 produces a printed output, because it has been set to verbose mode.