The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Test::Mock::Mango - Simple stubbing for Mango to allow unit tests for code that uses it

SYNOPSIS

  # Using Test::More
  #
  use Test::More;
  use Test::Mock::Mango; # Stubs in effect!
  # ...
  done_testing();


  # Using Test::Spec (uses Test::Spec::Mocks)
  #
  use Test::Spec;

  describe "Whilst stubbing Mango" => {
    require Test::Mock::Mango; # Stubs in effect in scope!
    # ...
  };
  runtests unless caller;

DESCRIPTION

Test::Mock::Mango provides simple stubbing of methods in the Mango library to allow easier unit testing of Mango based code.

It does not attempt to 100% replicate the functionality of Mango, but instead aims to provide "just enough" where sensible for the majority of use cases.

The stubbed methods ignore actual queries being entered and simply return a user-defined known data set. To run a test you need to set up the data you expect back first - this module doesn't test your queries, it allows you to test around Mango calls with known conditions.

STUBBED METHODS

The following methods are available on each faked part of the mango. We describe here briefly how far each actually simulates the real method.

Each method supports blocking and non-blocking syntax if the original method does. Non-blocking ops are not actually non blocking but simply execute your callback straight away as there's nothing to actually go off and do on an event loop.

All methods by default simuluate execution without errors. If you want to run a test that needs to respond to an error state you can do so by "Testing error states" in setting the error flag.

Collection

Test::Mock::Mango::Collection

aggregate

Ignores query. Returns current collection documents to simulate an aggregated result.

create

Doesn't really do anything.

drop

Doesn't really do anything.

find_one

Ignores query. Returns the first document from the current fake collection given in Test::Mock::Mango::FakeData. Returns undef if the collection is empty.

find_and_modify

Ignores query. Returns the first document from the current fake collection given in Test::Mock::Mango::FakeData. Returns undef if the collection is empty.

find

Ignores query. Returns a new Test::Mock::Mango::Cursor instance.

full_name

Returns full name of the fake collection.

insert

Naively inserts the given doc(s) onto the end of the current fake collection.

Returns an oid for each inserted document. If an _id is specifiec in the inserted doc then it is returned, otherwise a new Mango::BSON::ObjectID is returned instead.

update

Doesn't perform a real update. You should set the data state in $Test::Mock::Mango::data before making the call to be what you expect after the update.

remove

Doesn't remove anything.

Cursor

Test::Mock::Mango::Cursor

all

Return array ref containing all the documents in the current fake collection.

next

Simulates a cursor by (beginning at zero) iterating through each document on successive calls. Won't reset itself. If you want to reset the cursor then set Test::Mock::Mango-index> to zero.

count

Returns the number of documents in the current fake collection.

backlog

Arbitarily returns '2'

TESTING ERROR STATES

Test::Mock::Mango gives you the ability to simulate errors from your mango calls.

Simply set the error var before the call:

  $Test::Mock::Mango::error = 'oh noes!';

The next call will then run in an error state as if a real error has occurred. The error var is automatically cleared with the call so you don't need to undef it afterwards.

TESTING UPDATE/REMOVE FAILURES ETC

By default, Test::Mock::Mango is optimistic and assumes that any operation you perform has succeeded.

However, there are times when you want to do things in the event of a failure (e.g. when you attempt to update and the doc to update doesn't exist - this differs from "TESTING ERROR STATES" in that nothing is wrong with the call, and technically the operation has "succeeded" [mongodb is funny like that ;) ])

Mongodb normally reports this by a magic parameter called n that it passes back in the resultant doc. This is set to the number of documents that have been affected (e.g. if you remove two docs, it'll be set to 2, if you update 4 docs successfully it'll be set to 4).

In it's optimistic simulation, Test::Mock::Mango automaticaly sets the n value in return docs to 1. If your software cares about the n value and you want it set specifically (especially if you want to simulate say a "not updated" case) you can do this via the n value of $Test::Mock::MangoL

  $Test::Mock::Mango::n = 0; # The next call will now pretend no docs were updated

In the same way as using $Test::Mock::Mango::error, this value will be automatically cleared after the next call. If you want to reset it yourself at any point then set it to undef.

Examples

  my $doc = $mango->db('family')->collection('simpsons')->update(
    { name => 'Bart' },
    { name => 'Bartholomew' }
  );
  # $doc->{n} will be 1

  $Test::Mock::Mango::n = 0;
  my $doc = $mango->db('family')->collection('simpsons')->update(
    { name => 'Bart' },
    { name => 'Bartholomew' }
  );
  # $doc->{n} will be 0

AUTHOR

J Gregory <JGREGORY@CPAN.ORG>

SEE ALSO

Mango