grahamcarlyle-pmock-old-54365ce9139b/.hg_archival.txt0000644000000000000000000000022311564523304020454 0ustar 00000000000000repo: b84feefba34735a980ffbadb83204087e882b558 node: 54365ce9139b793da860797a9a4c097b831dc156 branch: default latesttag: null latesttagdistance: 3 grahamcarlyle-pmock-old-54365ce9139b/.hgignore0000644000000000000000000000007311564523304017174 0ustar 00000000000000syntax: glob *~ *.pyc syntax: regexp pmock.egg-info grahamcarlyle-pmock-old-54365ce9139b/TODO0000644000000000000000000000072511564523304016065 0ustar 00000000000000todo: + support for properties + add constraints and(), not(), or() + build scripts in CVS (Scons?) possibly: + constraint base class to allow non-derived constraints to default to an equality match against the parameter. Would allow more compact argument constraints for the common case of equality e.g. mock.foo('bar').will(...) + constrain allowable order of builder methods + pull out dispatcher functionality to allow different matching strategies (LIFO, FIFO)? grahamcarlyle-pmock-old-54365ce9139b/doc/index.html0000644000000000000000000000363111564523304020136 0ustar 00000000000000 pMock: a mock object library for Python

pMock has not been under active development since mid 2004.

For other suitable mocking frameworks see the Cheescake info on python mock testing tools

pMock

pMock is a Python module for testing Python code using mock objects.

...
import pmock
...
class InstrumentTest(unittest.TestCase):
    def test_low_quality_analysis(self):
        analyser_mock = pmock.Mock()
        analyser_mock.expects().analyse(pmock.eq("123")).will(pmock.return_value("30"))
        instrument = Instrument(analyser_mock)
        instrument.insert("sample#123")
        self.assert_(instrument.is_low_quality_indicator_on())
        analyser_mock.verify()
...

Inspired by the Java jMock library, pMock makes the writing of unit tests using mock object techniques easier.

The typical sequence of steps in a test involving pMock mock objects are: See the overview for an introduction on how to use pMock in your unit tests.

Requirements

Development

Bitbucket project page

Author: Graham Carlyle (grahamcarlyle at graham carlyle dot com)

grahamcarlyle-pmock-old-54365ce9139b/doc/overview.html0000644000000000000000000001470711564523304020703 0ustar 00000000000000 pMock: Overview of API

Overview of the pMock API

Creating mocks

A mock object is created to represent a real object for the purposes of a unit test. Using a mock object rather than the real object can be useful if the real object is difficult to construct, hasn't been written yet or causes awkward side effects in use.
    import pmock
    ...
    mock = pmock.Mock()
Expectations are defined for the methods that are meant to be called on the mock object.
    mock.expects(pmock.once()).render()
The mock can now be called with the expected method.
    mock.render()
Calling the mock with unexpected methods causes an exception to be raised.

When the mock objects have been set up, they are then used in the unit test as the real objects would have been.

    pictures = [mock]
    gallery = Gallery(pictures)
    gallery.render()
After the test's normal assertions have been made, an assertion that the mock's expectations have been satisfied should be made.
    mock.verify()
If any of the mock's expectations haven't been satisfied, such as an expected method not having been called, then the verify call raises an exception.

Argument expectations

Expectations can be set on the arguments passed to the mock's methods.
    mock.expects(pmock.once()).render(pmock.eq(640), pmock.eq(480))
The arguments to the expectation's mocked method are constraint objects which are evaluated on the actual arguments when a call is made to the mock object. If an argument doesn't satisfy its constraint then the expectation remains unsatisfied.
    mock.expects(pmock.once()).render(brush=pmock.same(print.BIG_BRUSH))
More flexible argument constraints can be defined using a slightly more verbose set of methods.
    mock.expects(pmock.once()).method("render") # any arguments allowed
    mock.expects(pmock.once()).method("render").with_at_least(brush=pmock.same(print.BIG_BRUSH))

Number of calls to the same method

The argument to the expects method describes how often the expected method can be called.
    mock.expects(pmock.once()).boil()
    mock.expects(pmock.at_least_once()).simmer()
    mock.expects(pmock.never()).fry()

Call order expectations

The order of calls to the mock object can be described with the after method.
    mock.expects(pmock.once()).invalidate()
    mock.expects(pmock.once()).render().after("invalidate")

An explicit id can be set for an expectation and used in the after method instead of using the method name.

    mock.expects(pmock.once()).add(pmock.eq(10)).id("add #1")
    mock.expects(pmock.once()).add(pmock.eq(15)).id("add #2").after("add #1")
    mock.expects(pmock.once()).add(pmock.eq(5)).after("add #2")
The order of calls can also be defined across different mock objects.
    other_mock = pmock.Mock()
    other_mock.expects(pmock.once()).add()
    mock = pmock.Mock()
    mock.expects(pmock.once()).sum().after("add", other_mock)

Mock behaviour

The mocked methods can be provided with simple behaviours using the will method.
    mock.expects(pmock.once()).calculate().will(pmock.return_value(20))
    mock.expects(pmock.once()).consume().will(pmock.raise_exception(RuntimeError("invalid")))

Stubs

Stubs allow behaviours to be specified for methods that can be called any number of times and are not to be included in the mock's verification check.
    mock.stubs().sleep().will(pmock.return_value(True))

Default behaviour for undefined methods

When an undefined method is called an exception is normally raised. However this behviour can be overridden by supplying a stub object to the Mock instance's set_default_stub method.
    mock.set_default_stub(pmock.return_value("legs"))
    mock.crazy()

From imports

The test code can be made more concise by importing the pmock module's public classes and functions into the test module.
    from pmock import *

    mock = Mock()
    mock.expects(once()).calculate(eq(34), eq(2)).will(return_value(68))

Test base class

The MockTestCase class is a convenience base class for tests. It provides the mock method for creating mock objects that will be automatically verified after the test method has run. The verify calls are considered to be part of the test and so are made to the mock object before tearDown has been called.
    class FooTest(pmock.MockTestCase):

        def test_involving_mocks(self):
            bar = self.mock()
            bar.expects(pmock.once()).baz()
            qux.quux(bar)
            # no need for verify call as its done by MockTestCase

Further information

Looking at the pMock acceptance tests may be helpful in further clarifying the behaviour of the module.

The mock objects and jmock websites contain useful information on mock objects and their use as a testing technique.

Martin Fowler has written an interesting article about mock objects and the style of unit testing that uses them.

Nat Pryce, one of the jmock authors, has written a response to Martin Fowler's article.

grahamcarlyle-pmock-old-54365ce9139b/examples/errors.py0000644000000000000000000000076111564523304021101 0ustar 00000000000000"""Show some test errors generated by pmock""" from pmock import * import unittest class ErrorsTest(unittest.TestCase): def test_unsatisfied_expectation(self): mock = Mock() mock.expects(once()).foo() mock.verify() def test_unexpected_call(self): mock = Mock() mock.foo() def test_conflicting_call(self): mock = Mock() mock.expects(never()).foo() mock.foo() if __name__ == '__main__': unittest.main() grahamcarlyle-pmock-old-54365ce9139b/examples/greeting.py0000644000000000000000000000321411564523304021365 0ustar 00000000000000import unittest from pmock import * class SystemError(Exception): def __init__(self, msg): self.msg = msg class Greeting: def __init__(self, system): self._system = system def message(self): try: (hours, seconds) = self._system.time() if hours < 12: return "Good morning" elif hours >= 12 and hours < 19: return "Good afternoon" else: return "Good evening" except SystemError, err: self._system.log("time problem: %s" % err.msg) return "Good day" class GreetingTest(MockTestCase): def setUp(self): self.system = self.mock() self.greeting = Greeting(self.system) def test_afternoon(self): self.system.expects(once()).time().will(return_value((12,10))) self.assertEqual(self.greeting.message(), "Good afternoon") def test_morning(self): self.system.expects(once()).time().will(return_value((6,50))) self.assertEqual(self.greeting.message(), "Good morning") def test_evening(self): self.system.expects(once()).time().will(return_value((19,50))) self.assertEqual(self.greeting.message(), "Good evening") def test_clock_failure(self): err_msg = "bzzz..malfunction" err = SystemError(err_msg) self.system.expects(once()).time().will(raise_exception(err)) self.system.expects(once()).log(string_contains(err_msg)) self.assertEqual(self.greeting.message(), "Good day") if __name__ == "__main__": unittest.main() grahamcarlyle-pmock-old-54365ce9139b/setup.py0000644000000000000000000000203211564523304017100 0ustar 00000000000000"""pMock: Python mock object framework. pMock provides support for creating mock objects for use in unit testing. The api is modelled on the jmock mock object framework. pMock is not under active development. """ classifiers = """\ Development Status :: 3 - Alpha Intended Audience :: Developers License :: OSI Approved :: Python Software Foundation License Programming Language :: Python Topic :: Software Development :: Libraries :: Python Modules Topic :: Software Development :: Testing """ from setuptools import setup doclines = __doc__.split("\n") setup ( name = "pmock", version = "0.3.1", maintainer="Graham Carlyle", maintainer_email="graham@grahamcarlyle.com", license="Same terms as Python", url = "https://bitbucket.org/grahamcarlyle/pmock-old", description = doclines[0], classifiers = filter(None, classifiers.split("\n")), long_description = "\n".join(doclines[2:]), package_dir = {"": "src"}, py_modules = ["pmock"], tests_require=["nose"], test_suite="nose.collector" ) grahamcarlyle-pmock-old-54365ce9139b/src/acceptance_tests.py0000644000000000000000000004247011564523304022051 0ustar 00000000000000import unittest import pmock import testsupport class MockMethodTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog") def test_uncalled_method(self): try: self.mock.verify() self.fail() except pmock.VerificationError: pass def test_called_method(self): self.mock.proxy().dog() self.mock.verify() def test_called_method_with_extra_arg(self): self.mock.proxy().dog("bone") self.mock.verify() def test_call_wrong_method(self): try: self.mock.proxy().cat() self.fail() except pmock.MatchError: pass def test_default_return_value(self): self.assertEqual(self.mock.proxy().dog(), None) def test_called_method_twice(self): self.mock.proxy().dog() try: self.mock.proxy().dog() self.fail() except pmock.MatchError: pass class MockMethodArgTestMixin(object): def test_uncalled_method(self): try: self.mock.verify() self.fail() except pmock.VerificationError: pass def test_method_with_correct_arg(self): self.mock.proxy().dog("bone") self.mock.verify() def test_call_method_with_incorrect_arg(self): try: self.mock.proxy().dog("carrot") self.fail() except pmock.MatchError: pass def test_call_method_with_insufficient_args(self): try: self.mock.proxy().dog() self.fail() except pmock.MatchError: pass def test_method_with_correct_arg_and_extras(self): self.mock.proxy().dog("bone", "biscuit") self.mock.verify() class MockMethodWithArgTest(MockMethodArgTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").with_(pmock.eq("bone")) def test_method_with_correct_arg_and_extras(self): try: self.mock.proxy().dog("bone", "biscuit") except pmock.MatchError: pass class MockMethodWithAtLeastArgTest(MockMethodArgTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").with_at_least( pmock.eq("bone")) def test_method_with_correct_arg_and_extras(self): self.mock.proxy().dog("bone", "biscuit") self.mock.verify() class MockMethodWithArgsTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.toys = ["ball", "stick"] self.mock.expects(pmock.once()).method("dog").with_( pmock.eq("bone"), pmock.same(self.toys), pmock.string_contains("slipper")) def test_method_with_correct_args(self): self.mock.proxy().dog("bone", self.toys, "bob's slipper") self.mock.verify() def test_call_method_with_insufficient_args(self): try: self.mock.proxy().dog("bone", "biscuit") self.fail() except pmock.MatchError: pass class MockMethodKeywordArgTestMixin(object): def test_uncalled_method(self): try: self.mock.verify() self.fail() except pmock.VerificationError: pass def test_method_with_correct_arg(self): self.mock.proxy().dog(food="bone") self.mock.verify() def test_call_method_with_incorrect_arg(self): try: self.mock.proxy().dog(food="ball") self.fail() except pmock.MatchError: pass def test_call_method_with_missing_arg(self): try: self.mock.proxy().dog(toy="ball") self.fail() except pmock.MatchError: pass class MockMethodWithKeywordArgTest(MockMethodKeywordArgTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").with_( food=pmock.eq("bone")) def test_method_with_correct_arg_and_extra(self): try: self.mock.proxy().dog(toy="ball", food="bone") except pmock.MatchError: pass class MockMethodWithAtLeastKeywordArgTest(MockMethodKeywordArgTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").with_at_least( food=pmock.eq("bone")) def test_method_with_correct_arg_and_extra(self): self.mock.proxy().dog(toy="ball", food="bone") self.mock.verify() class MockMethodWithNoArgsTestMixin(object): def test_method_with_no_args(self): self.mock.proxy().dog() self.mock.verify() def test_method_with_args(self): try: self.mock.proxy().dog("biscuit") self.fail() except pmock.MatchError: pass def test_method_with_kwargs(self): try: self.mock.proxy().dog(toy="ball") self.fail() except pmock.MatchError: pass class MockMethodWithNoArgsTest(MockMethodWithNoArgsTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").no_args() class MockMethodWithAnyArgsTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").any_args() def test_method_with_no_args(self): self.mock.proxy().dog() self.mock.verify() def test_method_with_args(self): self.mock.proxy().dog("biscuit") self.mock.verify() def test_method_with_kwargs(self): self.mock.proxy().dog(toy="ball") self.mock.verify() class MockMethodWillTest(unittest.TestCase): def test_method_will_return_value(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("dog").will( pmock.return_value("bone")) self.assertEqual(self.mock.proxy().dog(), "bone") def test_method_will_raise_exception(self): self.mock = pmock.Mock() custom_err = RuntimeError() self.mock.expects(pmock.once()).method("dog").will( pmock.raise_exception(custom_err)) try: self.mock.proxy().dog() self.fail() except RuntimeError, err: self.assert_(err is custom_err) self.mock.verify() class MockDirectMethodWithNoArgsTest(MockMethodWithNoArgsTestMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).dog() class MockDirectMethodAdditionalTest(unittest.TestCase): def test_expectation(self): mock = pmock.Mock() mock.expects(pmock.once()).dog( pmock.eq("bone"), food=pmock.eq("biscuit")).will( pmock.return_value("bark")) self.assert_(mock.proxy().dog("bone", food="biscuit"), "bark") class MockMultipleMethodsTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("cat") self.mock.expects(pmock.once()).method("cat").with_(pmock.eq("mouse")) def test_method_lifo_order(self): self.mock.proxy().cat("mouse") self.mock.proxy().cat() self.mock.verify() def test_uncalled_method(self): self.mock.proxy().cat() try: self.mock.verify() self.fail() except pmock.VerificationError: pass class SpecialMethodsTest(pmock.MockTestCase): def test_expected_specials(self): class Test(pmock.MockTestCase): def test_method(self): self.special = self.mock() self.special.expects(pmock.once()).__cmp__(pmock.eq("guppy")).\ will(pmock.return_value(0)) self.special.expects(pmock.once()).__call__(pmock.eq("blub"), pmock.eq("blub")) self.special == "guppy" self.special("blub", "blub") test = Test('test_method') result = unittest.TestResult() test(result) self.assertEqual(len(result.failures), 0) self.assertEqual(len(result.errors), 0) def test_unexpected_specials(self): class Test(pmock.MockTestCase): def test_method(self): self.special = self.mock() self.special == "guppy" test = Test('test_method') result = unittest.TestResult() test(result) self.assertEqual(len(result.failures), 1) self.assertEqual(len(result.errors), 0) class CallMockDirectlyTest(unittest.TestCase): def test_call_mock_rather_than_proxy(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("newt") self.mock.newt() self.mock.verify() class FifoExpectationTest(unittest.TestCase): def test_method_fifo_order(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("cat").with_(pmock.eq("mouse")) self.mock.expects(pmock.once()).method("cat") self.mock.proxy().cat(food="mouse") try: self.mock.proxy().cat() self.fail() except pmock.MatchError: pass class OnceTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("rabbit") def test_uncalled(self): try: self.mock.verify() except pmock.VerificationError: pass def test_call_once(self): self.mock.proxy().rabbit() self.mock.verify() def test_call_too_many(self): self.mock.proxy().rabbit() try: self.mock.proxy().rabbit() self.fail() except pmock.MatchError: pass class AtLeastOnceTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.at_least_once()).method("rabbit") def test_uncalled(self): try: self.mock.verify() except pmock.VerificationError: pass def test_call_once(self): self.mock.proxy().rabbit() self.mock.verify() def test_call_many(self): self.mock.proxy().rabbit() self.mock.proxy().rabbit() self.mock.proxy().rabbit() self.mock.proxy().rabbit() self.mock.verify() class NeverTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.never()).method("rabbit") def test_uncalled(self): self.mock.verify() def test_called(self): try: self.mock.proxy().rabbit() self.fail() except pmock.MatchError: pass class OrderedCallsBasicTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() self.mock.expects(pmock.once()).method("bull").id("bull call") self.mock.expects(pmock.once()).method("cow").after("bull call") def test_call_in_order(self): self.mock.proxy().bull() self.mock.proxy().cow() self.mock.verify() def test_call_out_of_order_doesnt_match(self): try: self.mock.proxy().cow() self.fail() except pmock.MatchError: pass class OrderedCallsAcrossMocksTest(unittest.TestCase): def setUp(self): self.mock1 = pmock.Mock("field") self.mock2 = pmock.Mock() self.mock1.expects(pmock.once()).method("bull").id("bovine") self.mock2.expects(pmock.once()).method("cow").after("bovine", self.mock1) def test_call_in_order(self): self.mock1.proxy().bull() self.mock2.proxy().cow() self.mock1.verify() self.mock2.verify() def test_call_out_of_order_doesnt_match(self): try: self.mock2.proxy().cow() self.fail() except pmock.MatchError: pass class OrderedCallsAdditionalTest(testsupport.ErrorMsgAssertsMixin, unittest.TestCase): def setUp(self): self.mock = pmock.Mock() def test_method_name_as_id(self): self.mock.expects(pmock.once()).method("bull") self.mock.expects(pmock.once()).method("cow").after("bull") self.mock.proxy().bull() self.mock.proxy().cow() self.mock.verify() def test_method_name_as_id_binds_to_last_matching_expectation(self): self.mock.expects(pmock.once()).method("cow").with_(pmock.eq("moo")) self.mock.expects(pmock.once()).method("cow").with_(pmock.eq("mooo")) self.mock.expects(pmock.once()).method("bull").after("cow") self.mock.proxy().cow("mooo") self.mock.proxy().bull() self.mock.proxy().cow("moo") self.mock.verify() def test_after_undefined_id_raises(self): try: self.mock.expects(pmock.once()).method("cow").after("ox") self.fail() except pmock.DefinitionError, err: self.assertUndefinedIdMsg(err.msg, "ox") def test_disallow_duplicate_ids(self): self.mock.expects(pmock.once()).method("cow").id("bovine") try: self.mock.expects(pmock.once()).method("bull").id("bovine") self.fail() except pmock.DefinitionError, err: self.assertDuplicateIdMsg(err.msg, "bovine") def test_disallow_duplicating_id_of_existing_method(self): self.mock.expects(pmock.once()).method("cow") try: self.mock.expects(pmock.once()).method("bovine").id("cow") self.fail() except pmock.DefinitionError, err: self.assertDuplicateIdMsg(err.msg, "cow") class StubTest(unittest.TestCase): def test_specified_like_expectations(self): mock = pmock.Mock() mock.stubs().method("fox") mock.stubs().method("fox").with_at_least("sly") mock.stubs().method("fox").with_("sly", meal="chicken") mock.stubs().method("fox").will(pmock.return_value("trot")) self.assertEqual(mock.proxy().fox(), "trot") mock.fox("sly", meal="chicken") mock.fox("sly") mock.fox() def test_uninvoked_doesnt_raise_verify(self): mock = pmock.Mock() mock.stubs().method("fox") mock.verify() def test_expectation_can_use_for_ordering(self): mock = pmock.Mock() mock.stubs().method("fox") mock.expects(pmock.once()).method("farmer").after("fox") mock.fox() mock.farmer() def test_set_default_stub(self): mock = pmock.Mock() mock.set_default_stub(pmock.return_value("trot")) self.assertEqual(mock.fox(), "trot") class ErrorMessageTest(unittest.TestCase): def test_expected_method_not_invoked(self): mock = pmock.Mock() mock.expects(pmock.once()).ant() try: mock.verify() except pmock.VerificationError, err: self.assertEqual( err.msg, "expected method was not invoked: expected once: ant()") def test_unmatched_method(self): mock = pmock.Mock() mock.stubs().mite(looks=pmock.eq("creepy")) mock.expects(pmock.once()).termite() mock.termite() try: mock.ant() except pmock.MatchError, err: self.assertEqual(err.msg, "no match found\n" "invoked ant()\n" "in:\n" "stub: mite(looks=pmock.eq('creepy')),\n" "expected once and has been invoked: termite()") def test_conflicting_method(self): mock = pmock.Mock() mock.expects(pmock.never()).cockroach() try: mock.cockroach() except pmock.MatchError, err: self.assertEqual(err.msg, "expected method to never be invoked\n" "invoked cockroach()\n" "in:\n" "expected not to be called: cockroach()") class MockTestCaseTest(unittest.TestCase): def test_verify_unsatisfied_expectation(self): class Test(pmock.MockTestCase): def test_method(self): mock = self.mock() mock.expects(pmock.once()).crow() test = Test('test_method') result = unittest.TestResult() test(result) self.assertEqual(len(result.failures), 1) self.assertEqual(len(result.errors), 0) traceback = result.failures[0][1] self.assert_(traceback.find('VerificationError') != -1) def test_verify_satisfied_expectation(self): class Test(pmock.MockTestCase): def test_method(self): mock = self.mock() mock.expects(pmock.once()).crow() mock.crow() test = Test('test_method') result = unittest.TestResult() test(result) self.assertEqual(len(result.failures), 0) self.assertEqual(len(result.errors), 0) if __name__ == '__main__': unittest.main() grahamcarlyle-pmock-old-54365ce9139b/src/pmock.py0000644000000000000000000005502211564523304017647 0ustar 00000000000000""" Python mock object framework, providing support for creating mock objects for use in unit testing. The api is modelled on the jmock mock object framework. Usage:: import pmock import unittest class PowerStation(object): def start_up(self, reactor): try: reactor.activate('core') except Exception, err: reactor.shutdown() class PowerStationTestCase(unittest.TestCase): def test_successful_activation(self): mock = pmock.Mock() mock.expects(pmock.once()).activate(pmock.eq('core')) PowerStation().start_up(mock) mock.verify() def test_problematic_activation(self): mock = pmock.Mock() mock.expects(pmock.once()).activate(pmock.eq('core')).will( pmock.raise_exception(RuntimeError('overheating'))) mock.expects(pmock.once()).shutdown() PowerStation().start_up(mock) mock.verify() if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://pmock.sourceforge.net/ Copyright (c) 2004, Graham Carlyle This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __author__ = "Graham Carlyle" __email__ = "graham at graham carlyle dot com" __version__ = "0.3.1" import unittest ############################################################################## # Exported classes and functions ############################################################################## __all__ = ["Mock", "MockTestCase", "once", "at_least_once", "never", "eq", "same", "string_contains", "functor", "return_value", "raise_exception"] ############################################################################## # Mock objects framework ############################################################################## class Error(AssertionError): def __init__(self, msg): AssertionError.__init__(self, msg) self.msg = msg def _mockers_str(cls, mockers): mockers_strs = [str(mocker) for mocker in mockers] return ", ".join(mockers_strs) _mockers_str = classmethod(_mockers_str) class VerificationError(Error): """An expectation have failed verification.""" def create_error(cls, msg, verified_invokable): err_msg = "%s: %s" % (msg, verified_invokable) return VerificationError(err_msg) create_error = classmethod(create_error) class MatchError(Error): """Method call unexpected.""" def create_error(cls, msg, invocation, mock): err_msg = "%s\ninvoked %s" % (msg, invocation) invokables_str = mock.invokables_str() if invokables_str != "": err_msg += "\nin:\n" + invokables_str return MatchError(err_msg) create_error = classmethod(create_error) class DefinitionError(Error): """Expectation definition isn't valid.""" def create_unregistered_id_error(cls, unregistered_id): msg = "reference to undefined id: %s" % unregistered_id return DefinitionError(msg) create_unregistered_id_error = classmethod( create_unregistered_id_error) def create_duplicate_id_error(cls, builder_id): msg = "id: %s is already defined" % builder_id return DefinitionError(msg) create_duplicate_id_error = classmethod(create_duplicate_id_error) class InvocationMocker(object): def __init__(self, invocation_matcher): self._matchers = [] self._invocation_matcher = invocation_matcher self._matchers.append(invocation_matcher) self._stub = None self._id = None def __str__(self): strs = ["%s: " % str(self._invocation_matcher)] for matcher in self._matchers[1:]: strs.append(str(matcher)) if self._stub is not None: strs.append(", %s" % self._stub) if self._id is not None: strs.append(" [%s]" % self._id) return "".join(strs) def add_matcher(self, matcher): self._matchers.append(matcher) def set_stub(self, stub): self._stub = stub def invoke(self, invocation): for matcher in self._matchers: matcher.invoked(invocation) if self._stub is not None: return self._stub.invoke(invocation) def matches(self, invocation): for matcher in self._matchers: if not matcher.matches(invocation): return False return True def set_id(self, mocker_id): self._id = mocker_id def verify(self): try: for matcher in self._matchers: matcher.verify() except AssertionError, err: raise VerificationError.create_error(str(err), self) class AbstractArgumentsMatcher(object): def __init__(self, arg_constraints=(), kwarg_constraints={}): self._arg_constraints = arg_constraints self._kwarg_constraints = kwarg_constraints def _arg_strs(self): arg_strs = [str(c) for c in self._arg_constraints] keywords = self._kwarg_constraints.keys() keywords.sort() for kw in keywords: constraint = self._kwarg_constraints[kw] arg_strs.append("%s=%s" % (kw, str(constraint))) return arg_strs def _matches_args(self, invocation): for i, constraint in enumerate(self._arg_constraints): if not constraint.eval(invocation.args[i]): return False return True def _matches_kwargs(self, invocation): for kw, constraint in self._kwarg_constraints.iteritems(): if (not invocation.kwargs.has_key(kw) or not constraint.eval(invocation.kwargs[kw])): return False return True def matches(self, invocation): return (self._matches_args(invocation) and self._matches_kwargs(invocation)) def invoked(self, invocation): pass def verify(self): pass class LeastArgumentsMatcher(AbstractArgumentsMatcher): def __str__(self): arg_strs = AbstractArgumentsMatcher._arg_strs(self) arg_strs.append("...") return "(%s)" % ", ".join(arg_strs) def _matches_args(self, invocation): if len(self._arg_constraints) > len(invocation.args): return False return AbstractArgumentsMatcher._matches_args(self, invocation) ANY_ARGS_MATCHER = LeastArgumentsMatcher() class AllArgumentsMatcher(AbstractArgumentsMatcher): def __str__(self): return "(%s)" % ", ".join(AbstractArgumentsMatcher._arg_strs(self)) def _matches_args(self, invocation): if len(self._arg_constraints) != len(invocation.args): return False return AbstractArgumentsMatcher._matches_args(self, invocation) def _matches_kwargs(self, invocation): for invocation_kw in invocation.kwargs.iterkeys(): if invocation_kw not in self._kwarg_constraints: return False return AbstractArgumentsMatcher._matches_kwargs(self, invocation) NO_ARGS_MATCHER = AllArgumentsMatcher() class MethodMatcher(object): def __init__(self, name): self._name = name def __str__(self): return self._name def matches(self, invocation): return invocation.name == self._name def invoked(self, invocation): pass def verify(self): pass class InvokedAfterMatcher(object): def __init__(self, invocation_recorder, description): self._invocation_recorder = invocation_recorder self._description = description def __str__(self): return ".after(%s)" % self._description def matches(self, invocation): return self._invocation_recorder.has_been_invoked() def invoked(self, invocation): pass def verify(self): pass class InvocationMockerBuilder(object): def __init__(self, mocker, builder_namespace): self._mocker = mocker self._builder_namespace = builder_namespace def __call__(self, *arg_constraints, **kwarg_constraints): self._mocker.add_matcher(AllArgumentsMatcher(arg_constraints, kwarg_constraints)) return self def __getattr__(self, name): """Define method name directly.""" self._mocker.add_matcher(MethodMatcher(name)) self._builder_namespace.register_method_name(name, self) return self def method(self, name): """Define method name.""" self._mocker.add_matcher(MethodMatcher(name)) self._builder_namespace.register_method_name(name, self) return self def with_(self, *arg_constraints, **kwarg_constraints): """Fully specify the method's arguments.""" self._mocker.add_matcher(AllArgumentsMatcher(arg_constraints, kwarg_constraints)) return self def with_at_least(self, *arg_constraints, **kwarg_constraints): """Specify the method's minimum required arguments.""" self._mocker.add_matcher(LeastArgumentsMatcher(arg_constraints, kwarg_constraints)) return self def any_args(self): """Method takes any arguments.""" self._mocker.add_matcher(ANY_ARGS_MATCHER) return self def no_args(self): """Method takes no arguments.""" self._mocker.add_matcher(NO_ARGS_MATCHER) return self def will(self, stub): """Set stub when method is called.""" self._mocker.set_stub(stub) return self def id(self, id_str): """Define a id for use in other mock's L{after} method.""" self._mocker.set_id(id_str) self._builder_namespace.register_unique_id(id_str, self) return self def after(self, id_str, other_mock=None): """Expected to be called after the method with supplied id.""" if other_mock is not None: builder_namespace = other_mock description = "%s on mock %s" % (repr(id_str), repr(other_mock.get_name())) else: builder_namespace = self._builder_namespace description = repr(id_str) builder = builder_namespace.lookup_id(id_str) if builder is None: raise DefinitionError.create_unregistered_id_error(id_str) invocation_recorder = InvokedRecorderMatcher() builder.match(invocation_recorder) matcher = InvokedAfterMatcher(invocation_recorder, description) self._mocker.add_matcher(matcher) return self def match(self, matcher): self._mocker.add_matcher(matcher) return self class Invocation(object): def __init__(self, name, args, kwargs): self.name = name self.args = args self.kwargs = kwargs def __str__(self): arg_strs = [repr(arg) for arg in self.args] keywords = self.kwargs.keys() keywords.sort() for kw in keywords: arg_strs.append("%s=%s" % (kw, repr(self.kwargs[kw]))) return "%s(%s)" % (self.name, ", ".join(arg_strs)) class BoundMethod(object): def __init__(self, name, mock): self._name = name self._mock = mock def __call__(self, *args, **kwargs): return self._mock.invoke(Invocation(self._name, args, kwargs)) class DefaultStub(object): def invoke(self, invocation): raise AssertionError("no match found") _DEFAULT_STUB = DefaultStub() def _special(method_name): def mocked_special(self, *args, **kwargs): return self._invoke_special(Invocation(method_name, args, kwargs)) return mocked_special class SpecialsMock(object): __call__ = _special("__call__") __cmp__ = _special("__cmp__") # assume no good reason to mock __del__ __delattr__ = _special("__delattr__") # __eq__, __ne__, etc. comparison operators covered by __cmp__ # __getattr__ & __getattribute__ needed for implementation __hash__ = _special("__hash__") # __init__ & __new__ needed for implementation __nonzero__ = _special("__nonzero__") __repr__ = _special("__repr__") # assume no good reason to mock __setattr__ __str__ = _special("__str__") # __unicode__ available if __str__ defined class Proxy(SpecialsMock): """A proxy for a mock object.""" def __init__(self, mock): self._mock = mock def __getattr__(self, attr_name): return BoundMethod(attr_name, self._mock) def _invoke_special(self, invocation): return self._mock._invoke_special(invocation) def mock_str(mock): return "" % id(mock) class Mock(SpecialsMock): """A mock object.""" def __init__(self, name=None): self._name = name self._invokables = [] self._proxy = Proxy(self) self._default_stub = _DEFAULT_STUB self._id_table = {} def __getattr__(self, attr_name): return BoundMethod(attr_name, self) def get_name(self): if self._name is not None: return self._name else: return mock_str(self) def _get_match_order_invokables(self): return self._invokables[::-1] # LIFO def lookup_id(self, builder_id): return self._id_table.get(builder_id, None) def register_unique_id(self, builder_id, builder): if self._id_table.has_key(builder_id): raise DefinitionError.create_duplicate_id_error(builder_id) self._id_table[builder_id] = builder def register_method_name(self, builder_id, builder): self._id_table[builder_id] = builder def invoke(self, invocation): try: matching_invokable = None for invokable in self._get_match_order_invokables(): if invokable.matches(invocation): return invokable.invoke(invocation) return self._default_stub.invoke(invocation) except AssertionError, err: raise MatchError.create_error(str(err), invocation, self) def _invoke_special(self, invocation): return self.invoke(invocation) def add_invokable(self, invokable): self._invokables.append(invokable) def invokables_str(self): invokable_strs = [str(invokable) for invokable in self._invokables] return ",\n".join(invokable_strs) def expects(self, invocation_matcher): """Define an expectation for a method. @return: L{InvocationMocker} """ mocker = InvocationMocker(invocation_matcher) self.add_invokable(mocker) return InvocationMockerBuilder(mocker, self) def stubs(self): """Define a method that may or may not be called. @return: L{InvocationMocker} """ mocker = InvocationMocker(_STUB_MATCHER_INSTANCE) self.add_invokable(mocker) return InvocationMockerBuilder(mocker, self) def set_default_stub(self, stub): """Set the default behaviour of undefined methods.""" self._default_stub = stub def proxy(self): """Return a proxy to the mock object. Proxies only have the mocked methods which may be useful if the mock's builder methods are in the way. """ return self._proxy def verify(self): """Check that the mock object has been called as expected.""" for invokable in self._get_match_order_invokables(): invokable.verify() class MockTestCase(unittest.TestCase): def __init__(self, methodName='runTest'): unittest.TestCase.__init__(self, methodName) self._test_method_name = methodName self._mocks = [] def _auto_verified_test(self): self._real_test_method() for mock in self._mocks: mock.verify() def __call__(self, result=None): self._mocks = [] self._real_test_method = getattr(self, self._test_method_name) setattr(self, self._test_method_name, self._auto_verified_test) unittest.TestCase.__call__(self, result) setattr(self, self._test_method_name, self._real_test_method) def mock(self): """Create a mock object that will be automatically verified after the test is run. """ mock = Mock() self._mocks.append(mock) return mock ############################################################################## # Mocked method stubs ############################################################################## class ReturnValueStub(object): def __init__(self, value): self._value = value def __str__(self): return "returns %s" % repr(self._value) def invoke(self, invocation): return self._value def return_value(value): """Stub that returns the supplied value. Convenience function for creating a L{ReturnValueStub} instance. """ return ReturnValueStub(value) class RaiseExceptionStub(object): def __init__(self, exception): self._exception = exception def __str__(self): return "raises %s" % self._exception def invoke(self, invocation): raise self._exception def raise_exception(exception): """Stub that raises the supplied exception. Convenience function for creating a L{RaiseExceptionStub} instance. """ return RaiseExceptionStub(exception) ############################################################################## # Invocation matchers ############################################################################## class InvokedRecorderMatcher(object): def __init__(self): self._invoked = False def has_been_invoked(self): return self._invoked def matches(self, invocation): return True def invoked(self, invocation): self._invoked = True def verify(self): pass class OnceInvocationMatcher(InvokedRecorderMatcher): def __str__(self): if self.has_been_invoked(): return "expected once and has been invoked" else: return "expected once" def matches(self, invocation): return not self.has_been_invoked() def verify(self): if not self.has_been_invoked(): raise AssertionError("expected method was not invoked") def once(): """Method will be called only once. Convenience function for creating a L{OnceInvocationMatcher} instance. """ return OnceInvocationMatcher() class AtLeastOnceInvocationMatcher(InvokedRecorderMatcher): def __str__(self): if self.has_been_invoked(): return "expected at least once and has been invoked" else: return "expected at least once" def matches(self, invocation): return True def verify(self): if not self.has_been_invoked(): raise AssertionError("expected method was not invoked") def at_least_once(): """Method will be called at least once. Convenience function for creating a L{AtLeastOnceInvocationMatcher} instance. """ return AtLeastOnceInvocationMatcher() class NotCalledInvocationMatcher(object): def __str__(self): return "expected not to be called" def invoked(self, invocation): raise AssertionError("expected method to never be invoked") def matches(self, invocation): return True def verify(self): pass _NOT_CALLED_MATCHER_INSTANCE = NotCalledInvocationMatcher() def never(): """Method will not be called. Convenience function for getting a L{NotCalledInvocationMatcher} instance. """ return _NOT_CALLED_MATCHER_INSTANCE class StubInvocationMatcher(object): def __str__(self): return "stub" def invoked(self, invocation): pass def matches(self, invocation): return True def verify(self): pass _STUB_MATCHER_INSTANCE = StubInvocationMatcher() ############################################################################## # Argument constraints ############################################################################## class EqConstraint(object): def __init__(self, expected): self._expected = expected def __repr__(self): return "%s.eq(%s)" % (__name__, repr(self._expected)) def eval(self, arg): return self._expected == arg def eq(expected): """Argument will be equal to supplied value. Convenience function for creating a L{EqConstraint} instance. """ return EqConstraint(expected) class SameConstraint(object): def __init__(self, expected): self._expected = expected def __repr__(self): return "%s.same(%s)" % (__name__, repr(self._expected)) def eval(self, arg): return self._expected is arg def same(expected): """Argument will be the same as the supplied reference. Convenience function for creating a L{SameConstraint} instance. """ return SameConstraint(expected) class StringContainsConstraint(object): def __init__(self, expected): self._expected = expected def __repr__(self): return "%s.string_contains(%s)" % (__name__, repr(self._expected)) def eval(self, arg): return (arg is not None) and (arg.find(self._expected) != -1) def string_contains(expected): """Argument contains the supplied substring. Convenience function for creating a L{StringContainsConstraint} instance. """ return StringContainsConstraint(expected) class FunctorConstraint(object): def __init__(self, boolean_functor): self._boolean_functor = boolean_functor def __repr__(self): return "%s.functor(%s)" % (__name__, repr(self._boolean_functor)) def eval(self, arg): return self._boolean_functor(arg) def functor(boolean_functor): """Supplied unary function evaluates to True when called with argument. Convenience function for creating a L{FunctorConstraint} instance. """ return FunctorConstraint(boolean_functor) grahamcarlyle-pmock-old-54365ce9139b/src/testsupport.py0000644000000000000000000000042211564523304021144 0ustar 00000000000000class ErrorMsgAssertsMixin: def assertUndefinedIdMsg(self, msg, label): self.assertEqual(msg, "reference to undefined id: %s" % label) def assertDuplicateIdMsg(self, msg, builder_id): self.assertEqual(msg, "id: %s is already defined" % builder_id) grahamcarlyle-pmock-old-54365ce9139b/src/unit_tests.py0000644000000000000000000011141011564523304020731 0ustar 00000000000000import unittest import pmock import testsupport class VerificationErrorTest(unittest.TestCase): def test_create_error(self): class Mocker: def __str__(self): return "matchers" error = pmock.VerificationError.create_error("problem", Mocker()) self.assertEqual(error.msg, "problem: matchers") class MatchErrorTest(unittest.TestCase): class MockInvocation: def __str__(self): return "call" class Mock: def __init__(self, invokables_str): self._str = invokables_str def invokables_str(self): return self._str def test_empty_invokables(self): error = pmock.MatchError.create_error("msg", self.MockInvocation(), self.Mock("")) self.assertEqual(error.msg, "msg\ninvoked call") def test_non_empty_invokables(self): error = pmock.MatchError.create_error("msg", self.MockInvocation(), self.Mock("invokables")) self.assertEqual(error.msg, "msg\ninvoked call\nin:\ninvokables") class ArgumentsMatcherTestMixin(object): def __init__(self, matcher_class): self.matcher_class = matcher_class def test_matches_arguments(self): arg1 = [] args_matcher = self.matcher_class((pmock.same(arg1),), {}) self.assert_( args_matcher.matches(pmock.Invocation("snake", (arg1,), {}))) def test_matches_keyword_arguments(self): arg2 = [] args_matcher = self.matcher_class((), {"food": pmock.same(arg2)}) invocation = pmock.Invocation("snake", (), {"food": arg2}) self.assert_(args_matcher.matches(invocation)) def test_matches_both_types_of_arguments(self): arg1 = [] arg2 = [] args_matcher = self.matcher_class((pmock.same(arg1),), {"food": pmock.same(arg2)}) invocation = pmock.Invocation("snake", (arg1,), {"food": arg2}) self.assert_(args_matcher.matches(invocation)) def test_insufficient_arguments(self): args_matcher = self.matcher_class((pmock.eq("slither"),), {}) self.assert_( not args_matcher.matches(pmock.Invocation("snake", (), {}))) def test_insufficient_keyword_arguments(self): args_matcher = self.matcher_class((), {"food": pmock.eq("goat")}) self.assert_( not args_matcher.matches(pmock.Invocation("snake", (), {}))) def test_unmatched_argument(self): class UnmatchedConstraint: def eval(self, invocation): return False args_matcher = self.matcher_class((UnmatchedConstraint(),), {}) invocation = pmock.Invocation("snake", ("slither",), {}) self.assert_(not args_matcher.matches(invocation)) def test_unmatched_keyword_argument(self): class UnmatchedConstraint: def eval(self, invocation): return False args_matcher = self.matcher_class((), {"food": UnmatchedConstraint()}) invocation = pmock.Invocation("snake", (), {"food": "goat"}) self.assert_(not args_matcher.matches(invocation)) class AllArgumentsMatcherTest(ArgumentsMatcherTestMixin, unittest.TestCase): def __init__(self, *args): ArgumentsMatcherTestMixin.__init__(self, pmock.AllArgumentsMatcher) unittest.TestCase.__init__(self, *args) def test_extra_arguments(self): args_matcher = pmock.AllArgumentsMatcher((pmock.eq("slither"),), {}) self.assert_(not args_matcher.matches( pmock.Invocation("snake", ("slither", "hiss"), {}))) def test_extra_keyword_arguments(self): args_matcher = pmock.AllArgumentsMatcher((), {"food": pmock.eq("goat")}) self.assert_(not args_matcher.matches( pmock.Invocation("snake", (), {"food": "goat", "colour": "red"}))) def test_no_arguments(self): args_matcher = pmock.AllArgumentsMatcher() self.assert_(args_matcher.matches(pmock.Invocation("snake", (), {}))) self.assert_( not args_matcher.matches(pmock.Invocation("snake", ("hiss",), {}))) self.assert_(not args_matcher.matches( pmock.Invocation("snake", (), {"food": "goat"}))) def test_str(self): matcher = pmock.AllArgumentsMatcher((pmock.eq("slither"),), {"food": pmock.eq("goat")}) self.assertEqual(str(matcher), "(pmock.eq('slither'), food=pmock.eq('goat'))") def test_empty_str(self): self.assertEqual(str(pmock.AllArgumentsMatcher()), "()") class LeastArgumentsMatcherTest(ArgumentsMatcherTestMixin, unittest.TestCase): def __init__(self, *args): ArgumentsMatcherTestMixin.__init__(self, pmock.LeastArgumentsMatcher) unittest.TestCase.__init__(self, *args) def test_extra_arguments(self): args_matcher = pmock.LeastArgumentsMatcher((pmock.eq("slither"),), {}) self.assert_(args_matcher.matches( pmock.Invocation("snake", ("slither", "hiss"), {}))) def test_extra_keyword_arguments(self): args_matcher = pmock.LeastArgumentsMatcher((), {"food": pmock.eq("goat")}) self.assert_(args_matcher.matches( pmock.Invocation("snake", (), {"food": "goat", "colour": "red"}))) def test_any_arguments(self): args_matcher = pmock.LeastArgumentsMatcher() self.assert_(args_matcher.matches(pmock.Invocation("snake", (), {}))) self.assert_( args_matcher.matches(pmock.Invocation("snake", ("hiss",), {}))) self.assert_(args_matcher.matches( pmock.Invocation("snake", ("constrict",), {"food": "goat"}))) def test_str(self): matcher = pmock.LeastArgumentsMatcher((pmock.eq("slither"),), {"food": pmock.eq("goat")}) self.assertEqual(str(matcher), "(pmock.eq('slither'), food=pmock.eq('goat'), ...)") def test_empty_str(self): self.assertEqual(str(pmock.LeastArgumentsMatcher()), "(...)") class InvocationMockerTest(unittest.TestCase): class MockMatcher: def __init__(self, matches): self._matches = matches def matches(self, invocation): self.matches_invocation = invocation return self._matches def invoked(self, invocation): self.invoked_invocation = invocation def test_matches(self): mocker = pmock.InvocationMocker(self.MockMatcher(True)) self.assert_(mocker.matches(pmock.Invocation("duck", (), {}))) def test_unmatched(self): mocker = pmock.InvocationMocker(self.MockMatcher(False)) self.assert_(not mocker.matches(pmock.Invocation("duck", (), {}))) def test_added_matcher_unmatched(self): mocker = pmock.InvocationMocker(self.MockMatcher(True)) mocker.add_matcher(self.MockMatcher(False)) self.assert_(not mocker.matches(pmock.Invocation("duck", (), {}))) def test_matches_passes_invocation_to_matcher(self): matcher = self.MockMatcher(True) mocker = pmock.InvocationMocker(matcher) invocation = pmock.Invocation("duck", (), {}) mocker.matches(invocation) self.assertEqual(matcher.matches_invocation, invocation) def test_no_stub_returns_none(self): mocker = pmock.InvocationMocker(self.MockMatcher(True)) self.assert_(mocker.invoke(pmock.Invocation("duck", (), {})) is None) def test_invoke_returns_stubs_value(self): class MockStub: def invoke(self, invocation): return 'value' mocker = pmock.InvocationMocker(self.MockMatcher(True)) mocker.set_stub(MockStub()) self.assert_(mocker.invoke(pmock.Invocation("duck", (), {})) == 'value') def test_invoke_passes_invocation_to_matcher(self): matcher1 = self.MockMatcher(True) matcher2 = self.MockMatcher(True) mocker = pmock.InvocationMocker(matcher1) mocker.add_matcher(matcher2) invocation = pmock.Invocation("duck", (), {}) mocker.invoke(invocation) self.assertEqual(matcher1.invoked_invocation, invocation) self.assertEqual(matcher2.invoked_invocation, invocation) def test_verify(self): class MockInvocationMatcher: def __init__(self, raises, str_str): self.raises = raises self.str_str = str_str self.verified = False def __str__(self): return self.str_str def verify(self): self.verified = True if self.raises: raise AssertionError("problem") matcher1 = MockInvocationMatcher(False, "one") matcher2 = MockInvocationMatcher(True, "two") matcher3 = MockInvocationMatcher(True, "three") mocker = pmock.InvocationMocker(matcher1) mocker.add_matcher(matcher2) mocker.add_matcher(matcher3) try: mocker.verify() self.fail("expected verify to raise") except pmock.VerificationError, err: self.assert_(matcher1.verified) self.assert_(matcher2.verified) self.assert_(not matcher3.verified) self.assertEqual(err.msg, "problem: %s" % mocker) def test_str(self): class MockMatcher: def __init__(self, str_str): self._str = str_str def __str__(self): return self._str MockStub = MockMatcher mocker = pmock.InvocationMocker(MockMatcher("invocation_matcher")) mocker.add_matcher(MockMatcher("added_matcher1")) mocker.add_matcher(MockMatcher("added_matcher2")) mocker.set_stub(MockStub("stub")) self.assertEqual(str(mocker), "invocation_matcher: added_matcher1added_matcher2, " "stub") def test_no_id_str(self): class MockMatcher: def __init__(self, str_str): self._str = str_str def __str__(self): return self._str mocker = pmock.InvocationMocker(MockMatcher("invocation_matcher")) mocker.add_matcher(MockMatcher("added_matcher1")) self.assertEqual(str(mocker), "invocation_matcher: added_matcher1") def test_id_str(self): class MockMatcher: def __init__(self, str_str): self._str = str_str def __str__(self): return self._str MockStub = MockMatcher mocker = pmock.InvocationMocker(MockMatcher("invocation_matcher")) mocker.add_matcher(MockMatcher("added_matcher1")) mocker.set_stub(MockStub("stub")) mocker.set_id("quack") self.assertEqual(str(mocker), "invocation_matcher: added_matcher1, stub [quack]") class InvocationMockerBuilderTest(testsupport.ErrorMsgAssertsMixin, unittest.TestCase): class MockInvocationMocker: def __init__(self): self.added_matchers = [] self.id = None self.stub = None def add_matcher(self, matcher): self.added_matchers.append(matcher) def set_id(self, mocker_id): self.id = mocker_id def set_stub(self, stub): self.stub = stub def _get_only_added_matcher(self): if len(self.added_matchers) != 1: raise AssertionError('more than one matcher has been added') return self.added_matchers[0] added_matcher = property(_get_only_added_matcher) def setUp(self): self.mocker = self.MockInvocationMocker() self.builder_namespace = pmock.Mock() self.builder = pmock.InvocationMockerBuilder(self.mocker, self.builder_namespace) def test_add_method_matcher(self): self.assert_(self.builder.method("chicken") is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.MethodMatcher)) self.assert_(self.mocker.added_matcher.matches( pmock.Invocation("chicken", (), {}))) self.assertEqual(self.builder_namespace.lookup_id("chicken"), self.builder) def test_add_direct_method_matcher(self): self.assert_(self.builder.chicken() is not None) self.assert_(isinstance(self.mocker.added_matchers[0], pmock.MethodMatcher)) self.assert_(self.mocker.added_matchers[0].matches( pmock.Invocation("chicken", (), {}))) self.assert_(self.mocker.added_matchers[1].matches( pmock.Invocation("chicken", (), {}))) self.assertEqual(self.builder_namespace.lookup_id("chicken"), self.builder) def test_add_direct_method_and_arg_matcher(self): self.assert_(self.builder.chicken(pmock.eq("egg")) is not None) self.assert_(isinstance(self.mocker.added_matchers[0], pmock.MethodMatcher)) self.assert_(self.mocker.added_matchers[0].matches( pmock.Invocation("chicken", (), {}))) self.assert_(self.mocker.added_matchers[1].matches( pmock.Invocation("chicken", ("egg",), {}))) self.assertEqual(self.builder_namespace.lookup_id("chicken"), self.builder) def test_add_with_matcher(self): self.assert_(self.builder.with_(pmock.eq("egg")) is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.AllArgumentsMatcher)) self.assert_(self.mocker.added_matcher.matches( pmock.Invocation(None, ("egg",), {}))) def test_add_with_at_least_matcher(self): self.assert_(self.builder.with_at_least(pmock.eq("egg")) is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.LeastArgumentsMatcher)) self.assert_(self.mocker.added_matcher.matches( pmock.Invocation(None, ("egg", "feather"), {}))) def test_add_no_args_matcher(self): self.assert_(self.builder.no_args() is not None) self.assertEqual(self.mocker.added_matcher, pmock.NO_ARGS_MATCHER) def test_add_any_args_matcher(self): self.assert_(self.builder.any_args() is not None) self.assertEqual(self.mocker.added_matcher, pmock.ANY_ARGS_MATCHER) def test_set_will_stub(self): class MockStub: pass stub = MockStub() self.assert_(self.builder.will(stub) is not None) self.assertEqual(self.mocker.stub, stub) def test_set_id(self): self.assert_(self.builder.id("poultry") is not None) self.assertEqual(self.mocker.id, "poultry") self.assertEqual(self.builder_namespace.lookup_id("poultry"), self.builder) def test_set_duplicate_id(self): self.builder.id("poultry") try: self.builder.id("poultry") self.fail("mocker with duplicate ids should raise") except pmock.DefinitionError, err: self.assertDuplicateIdMsg(err.msg, "poultry") def test_add_after_ordering(self): builder2 = pmock.InvocationMockerBuilder(self.MockInvocationMocker(), self.builder_namespace) builder2.id("rooster") self.assert_(self.builder.after("rooster") is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.InvokedAfterMatcher)) def test_after_undefined_id(self): try: self.builder.after("rooster") except pmock.DefinitionError, err: self.assertUndefinedIdMsg(err.msg, "rooster") def test_add_after_other_named_mock_ordering(self): other_mock = pmock.Mock("coup") other_mock.expects(pmock.OnceInvocationMatcher()).method("rooster") self.assert_(self.builder.after("rooster", other_mock) is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.InvokedAfterMatcher)) self.assertEqual(str(self.mocker.added_matcher), ".after('rooster' on mock 'coup')") def test_add_after_other_unnamed_mock_ordering(self): other_mock = pmock.Mock() other_mock.expects(pmock.OnceInvocationMatcher()).method("rooster") self.assert_(self.builder.after("rooster", other_mock) is not None) self.assert_(isinstance(self.mocker.added_matcher, pmock.InvokedAfterMatcher)) self.assertEqual(str(self.mocker.added_matcher), ".after('rooster' on mock '%s')" % pmock.mock_str(other_mock)) def test_match(self): class CustomMatcher: pass custom_matcher = CustomMatcher() self.assert_(self.builder.match(custom_matcher) is not None) self.assertEqual(self.mocker.added_matcher, custom_matcher) class MethodMatcherTest(unittest.TestCase): def setUp(self): self.method_matcher = pmock.MethodMatcher("horse") def test_matches(self): self.assert_( self.method_matcher.matches(pmock.Invocation("horse", (), {}))) def test_unmatched(self): self.assert_( not self.method_matcher.matches(pmock.Invocation("ass", (), {}))) def test_str(self): self.assertEqual(str(self.method_matcher), "horse") class InvokedAfterMatcherTest(unittest.TestCase): def setUp(self): self.invocation_recorder = pmock.InvokedRecorderMatcher() self.matcher = pmock.InvokedAfterMatcher(self.invocation_recorder, "'weasel'") self.invocation = pmock.Invocation("stoat", (), {}) def test_uninvoked_doesnt_match(self): self.assert_(not self.matcher.matches(self.invocation)) def test_invoked_matches(self): self.invocation_recorder.invoked(self.invocation) self.assert_(self.matcher.matches(self.invocation)) def test_str(self): self.assertEqual(str(self.matcher), ".after('weasel')") class InvocationTest(unittest.TestCase): def test_no_args_str(self): self.assertEqual(str(pmock.Invocation("penguin", (), {})), "penguin()") def test_arg_str(self): self.assertEqual(str(pmock.Invocation("penguin", ("swim",), {})), "penguin('swim')") def test_kwarg_str(self): self.assertEqual( str(pmock.Invocation("penguin", (), {"food": "fish"})), "penguin(food='fish')") def test_args_str(self): self.assertEqual( str(pmock.Invocation("penguin", ("swim", "waddle"), {"home": "iceberg", "food": "fish"})), "penguin('swim', 'waddle', food='fish', home='iceberg')") class ProxyTest(unittest.TestCase): def test_invoke(self): class Mock: def invoke(self, invocation): self.invocation = invocation mock = Mock() proxy = pmock.Proxy(mock) proxy.camel("walk", desert="gobi") self.assertEqual(mock.invocation.name, "camel") self.assertEqual(mock.invocation.args, ("walk",)) self.assertEqual(mock.invocation.kwargs, {"desert": "gobi"}) class MockTest(unittest.TestCase): def test_one_to_one_proxy(self): mock = pmock.Mock() self.assert_(mock.proxy() is mock.proxy()) def test_unmatched_invocation(self): mock = pmock.Mock() try: mock.invoke(pmock.Invocation("wolf", (), {})) self.fail("should have raised due to unexpected method call") except pmock.MatchError, err: self.assertEqual(err.msg, "no match found\n" "invoked wolf()") def test_matching_invokable(self): class Invokable: def matches(self, invocation): self.matches_invocation = invocation return True def invoke(self, invocation): self.invoke_invocation = invocation invokable = Invokable() mock = pmock.Mock() mock.add_invokable(invokable) invocation = pmock.Invocation("wolf", (), {}) mock.invoke(invocation) self.assertEqual(invokable.matches_invocation, invocation) self.assertEqual(invokable.invoke_invocation, invocation) def test_lifo_matching_order(self): class Invokable: current_attempt_number = 1 def __init__(self, matches): self._matches = matches self.attempt_number = None self.invoked = False def matches(self, invocation): self.attempt_number = Invokable.current_attempt_number Invokable.current_attempt_number += 1 return self._matches def invoke(self, invocation): self.invoked = True invokable1 = Invokable(False) invokable2 = Invokable(True) invokable3 = Invokable(False) mock = pmock.Mock() mock.add_invokable(invokable1) mock.add_invokable(invokable2) mock.add_invokable(invokable3) mock.invoke(pmock.Invocation("wolf", (), {})) self.assert_(invokable1.attempt_number is None) self.assert_(not invokable1.invoked) self.assertEqual(invokable2.attempt_number, 2) self.assert_(invokable2.invoked) self.assertEqual(invokable3.attempt_number, 1) self.assert_(not invokable3.invoked) def test_lifo_verify_order(self): class Invokable: def __init__(self, raises): self.verified = False self.raises = raises def verify(self): self.verified = True if self.raises: raise pmock.VerificationError("problem") invokable1 = Invokable(False) invokable2 = Invokable(True) invokable3 = Invokable(False) mock = pmock.Mock() mock.add_invokable(invokable3) mock.add_invokable(invokable2) mock.add_invokable(invokable1) try: mock.verify() self.fail("expected verify to raise") except pmock.VerificationError: self.assert_(invokable1.verified) self.assert_(invokable2.verified) self.assert_(not invokable3.verified) def test_invokables_str(self): class Invokable: def __init__(self, str_str): self._str = str_str def __str__(self): return self._str mock = pmock.Mock() self.assertEqual(mock.invokables_str(), "") mock.add_invokable(Invokable("howl")) self.assertEqual(mock.invokables_str(), "howl") mock.add_invokable(Invokable("bark")) self.assertEqual(mock.invokables_str(), "howl,\nbark") mock.add_invokable(Invokable("growl")) self.assertEqual(mock.invokables_str(), "howl,\nbark,\ngrowl") def test_expects(self): mock = pmock.Mock() mock.expects(pmock.OnceInvocationMatcher()).method("howl") self.assert_(mock.lookup_id("howl") is not None) self.assertRaises(pmock.VerificationError, mock.verify) def test_stubs(self): mock = pmock.Mock() mock.stubs().method("growl") self.assert_(mock.lookup_id("growl") is not None) mock.verify() def test_set_default_stub(self): class Stub: def invoke(self, invocation): return "bark" stub = Stub() mock = pmock.Mock() mock.set_default_stub(stub) self.assertEquals(mock.foo(), "bark") def test_get_unnamed(self): mock = pmock.Mock() self.assertEqual(mock.get_name(), pmock.mock_str(mock)) def test_get_name(self): mock = pmock.Mock("white fang") self.assertEqual(mock.get_name(), "white fang") def test_invoke_directly(self): class Invokable: def matches(self, invocation): self.invocation = invocation return True def invoke(self, invocation): pass mock = pmock.Mock() invokable = Invokable() mock.add_invokable(invokable) mock.howl(under='moon') self.assertEqual(invokable.invocation.name, "howl") self.assertEqual(invokable.invocation.kwargs['under'], "moon") class MockSpecialsTest(unittest.TestCase): def setUp(self): self.mock = pmock.Mock() class Invokable: def __init__(self): self.returnValue = None def matches(self, invocation): self.invocation = invocation return True def invoke(self, invocation): return self.returnValue self.invokable = Invokable() self.mock.add_invokable(self.invokable) def assertInvocation(self, method_name, args, kwargs): self.assertEqual(self.invokable.invocation.name, method_name) self.assertEqual(self.invokable.invocation.args, args) self.assertEqual(self.invokable.invocation.kwargs, kwargs) def test_special_on_proxy(self): proxy = self.mock.proxy() proxy("growl") self.assertInvocation("__call__", ("growl",), {}) def test_call(self): self.mock("howl", bite="big") self.assertInvocation("__call__", ("howl",), {"bite": "big"}) def test_cmp(self): self.invokable.returnValue = 0 cmp(self.mock, "mouse") self.assertInvocation("__cmp__", ("mouse",), {}) def test_delattr(self): del self.mock.fangs self.assertInvocation("__delattr__", ("fangs",), {}) def test_hash(self): self.invokable.returnValue = 0 hash(self.mock) self.assertInvocation("__hash__", (), {}) def test_non_zero(self): self.invokable.returnValue = True bool(self.mock) self.assertInvocation("__nonzero__", (), {}) def test_repr(self): self.invokable.returnValue = "mock" repr(self.mock) self.assertInvocation("__repr__", (), {}) def test_str(self): self.invokable.returnValue = "mock" str(self.mock) self.assertInvocation("__str__", (), {}) def test_unicode(self): self.invokable.returnValue = "mock" unicode(self.mock) self.assertInvocation("__str__", (), {}) class RegisterIdTest(testsupport.ErrorMsgAssertsMixin, unittest.TestCase): def setUp(self): class MockBuilder: pass self.builder = MockBuilder() self.mock = pmock.Mock() self.mock.register_unique_id("howler", self.builder) def test_register_unique_id(self): self.assertEqual(self.mock.lookup_id("howler"), self.builder) def test_register_duplicate_id(self): try: self.mock.register_unique_id("howler", self.builder) except pmock.DefinitionError, err: self.assertDuplicateIdMsg(err.msg, "howler") def test_lookup_unknown_id(self): self.assert_(self.mock.lookup_id("growler") is None) class RegisterMethodNameTest(testsupport.ErrorMsgAssertsMixin, unittest.TestCase): class MockBuilder: pass def setUp(self): self.builder = self.MockBuilder() self.mock = pmock.Mock() self.mock.register_method_name("wolf", self.builder) def test_register_method_name(self): self.assertEqual(self.mock.lookup_id("wolf"), self.builder) def test_register_method_again(self): another_builder = self.MockBuilder() self.mock.register_method_name("wolf", another_builder) self.assertEqual(self.mock.lookup_id("wolf"), another_builder) class MockTestCaseTest(unittest.TestCase): def test_no_mocks_created(self): class Test(pmock.MockTestCase): def test_method(self): pass test = Test('test_method') result = unittest.TestResult() test(result) self.assert_(result.wasSuccessful()) def test_created_mock(self): created_mocks = [] class Test(pmock.MockTestCase): def test_method(self): created_mocks.append(self.mock()) test = Test('test_method') result = unittest.TestResult() test(result) self.assert_(result.wasSuccessful(), 'errors %s, failures %s' % (result.errors, result.failures)) self.assert_(isinstance(created_mocks[0], pmock.Mock)) def test_created_mocks_are_verified(self): class MockMatcher: def verify(self): self.is_verified = True matcher = MockMatcher() class Test(pmock.MockTestCase): def test_method(self): self.mock().expects(matcher) test = Test('test_method') test() self.assert_(matcher.is_verified) def test_raised_verify_is_failure(self): class MockMatcher: def verify(self): raise pmock.VerificationError('oops') matcher = MockMatcher() class Test(pmock.MockTestCase): def test_method(self): self.mock().expects(matcher) test = Test('test_method') result = unittest.TestResult() test(result) self.assertEqual(len(result.failures), 1) self.assertEqual(len(result.errors), 0) def test_auto_verify_order(self): events = [] class MockMatcher: def verify(self): events.append('verify') matcher = MockMatcher() class Test(pmock.MockTestCase): def setUp(self): events.append('setUp') def tearDown(self): events.append('tearDown') def test_method(self): self.mock().expects(matcher) events.append('test') test = Test('test_method') result = unittest.TestResult() test() self.assertEqual(events, ['setUp', 'test', 'verify', 'tearDown']) ############################################################################## # Mocked method stubs ############################################################################## class ReturnValueTest(unittest.TestCase): def setUp(self): self.stub = pmock.ReturnValueStub("owl") def test_invoke(self): self.assertEqual(self.stub.invoke(pmock.Invocation("hoot", (), {})), "owl") def test_str(self): self.assertEqual(str(self.stub), "returns 'owl'") class RaiseExceptionStub(unittest.TestCase): def setUp(self): self.exception = RuntimeError("owl") self.stub = pmock.RaiseExceptionStub(self.exception) def test_invoke(self): try: self.stub.invoke(pmock.Invocation("hoot", (), {})) self.fail("expected exception to be raised") except RuntimeError, err: self.assertEqual(err, self.exception) def test_str(self): self.assertEqual(str(self.stub), "raises %s" % self.exception) ############################################################################## # Invocation matchers ############################################################################## class OnceInvocationMatcherTest(unittest.TestCase): def setUp(self): self.matcher = pmock.OnceInvocationMatcher() def test_uninvoked_matches(self): self.assert_(self.matcher.matches(pmock.Invocation("worm", (), {}))) def test_invoked_doesnt_match(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.assert_( not self.matcher.matches(pmock.Invocation("snake", (), {}))) def test_verify_uninvoked(self): try: self.matcher.verify() self.fail("expected verify to raise") except AssertionError, err: self.assertEqual("expected method was not invoked", str(err)) def test_verify_invoked(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.matcher.verify() def test_uninvoked_str(self): self.assertEqual(str(self.matcher), "expected once") def test_invoked_str(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.assertEqual(str(self.matcher), "expected once and has been invoked") class AtLeastOnceInvocationMatcherTest(unittest.TestCase): def setUp(self): self.matcher = pmock.AtLeastOnceInvocationMatcher() def test_uninvoked_matches(self): self.assert_(self.matcher.matches(pmock.Invocation("worm", (), {}))) def test_invoked_matches(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.assert_(self.matcher.matches(pmock.Invocation("snake", (), {}))) def test_verify_uninvoked(self): try: self.matcher.verify() self.fail("expected verify to raise") except AssertionError, err: self.assertEqual("expected method was not invoked", str(err)) def test_verify_invoked(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.matcher.verify() def test_uninvoked_str(self): self.assertEqual(str(self.matcher), "expected at least once") def test_invoked_str(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.assertEqual(str(self.matcher), "expected at least once and has been invoked") class NotCalledInvocationMatcherTest(unittest.TestCase): def setUp(self): self.matcher = pmock.NotCalledInvocationMatcher() def test_uninvoked_matches(self): self.assert_(self.matcher.matches(pmock.Invocation("worm", (), {}))) def test_invoke_raises(self): try: self.matcher.invoked(pmock.Invocation("worm", (), {})) self.fail("expected exception to be raised") except AssertionError, err: self.assertEqual(str(err), "expected method to never be invoked") def test_verify_uninvoked(self): self.matcher.verify() def test_str(self): self.assertEqual(str(self.matcher), "expected not to be called") class StubInvocationMatcherTest(unittest.TestCase): def setUp(self): self.matcher = pmock.StubInvocationMatcher() def test_uninvoked_matches(self): self.assert_(self.matcher.matches(pmock.Invocation("worm", (), {}))) def test_verify_uninvoked(self): self.matcher.verify() def test_verify_invoked(self): self.matcher.invoked(pmock.Invocation("worm", (), {})) self.matcher.verify() def test_str(self): self.assertEqual(str(self.matcher), "stub") ############################################################################## # Argument constraints ############################################################################## class EqConstraintTest(unittest.TestCase): def test_match(self): self.assert_(pmock.EqConstraint("mouse").eval("mouse")) def test_umatched(self): self.assert_(not pmock.EqConstraint("mouse").eval("rat")) def test_str(self): self.assertEqual(str(pmock.EqConstraint("mouse")), "pmock.eq('mouse')") class SameConstraintTest(unittest.TestCase): def test_match(self): mutable = ["mouse"] self.assert_(pmock.SameConstraint(mutable).eval(mutable)) def test_umatched(self): self.assert_(not pmock.SameConstraint(["mouse"]).eval(["mouse"])) def test_str(self): self.assertEqual(str(pmock.SameConstraint(["mouse"])), "pmock.same(['mouse'])") class StringContainsConstraintTest(unittest.TestCase): def test_matches_same_string(self): self.assert_(pmock.StringContainsConstraint("mouse").eval("mouse")) def test_matches_substring(self): self.assert_(pmock.StringContainsConstraint("mo").eval("mouse")) self.assert_(pmock.StringContainsConstraint("ou").eval("mouse")) self.assert_(pmock.StringContainsConstraint("se").eval("mouse")) self.assert_(pmock.StringContainsConstraint("").eval("mouse")) def test_umatched(self): self.assert_(not pmock.StringContainsConstraint("mouse").eval("rat")) self.assert_(not pmock.StringContainsConstraint("mouse").eval(None)) def test_str(self): self.assertEqual(str(pmock.StringContainsConstraint("mouse")), "pmock.string_contains('mouse')") class FunctorConstraintTest(unittest.TestCase): def test_matches(self): self.assert_(pmock.FunctorConstraint(lambda arg: True).eval("mouse")) def test_umatched(self): self.assert_( not pmock.FunctorConstraint(lambda arg: False).eval("mouse")) def test_str(self): lambda_ = lambda arg: False self.assertEqual(str(pmock.FunctorConstraint(lambda_)), "pmock.functor(%s)" % repr(lambda_)) if __name__ == '__main__': unittest.main()