Python mocking- understand the concept and necessity
Question: **First of all I really want to understand WHY should I use mocking (Python
Mock library).**

What's the difference between quickly making a small object for the need of
testing something and using a mock object?

What are the advantages of mocking over other methods (I would really need
some "live" examples to understand this one)? Is mocking essential in some
cases?

Also: what's the difference between a mock object and magicmock object? How to
they connect?

**The second thing is WHAT/WHERE to mock.**

Should I only mock, for example, the database query results? I mean: does the
mocked data should always be a remote one?

**tl;dr:** Please explain the mocking concept in Python to someone who never
used it in any language.


Answer: A mock object is meant to quickly and easily represent some complex object
without having to manually go through and set up stubs for that object during
a test. It's simply a useful utility for making writing tests a bit easier.

As to what/where to mock, anything that is external to the module-under-test
should be mocked. All you want to test is the current module code, not the
code for some module that is being called by the module-under-test.

A quick example is some code that uses the simplejson module.

    
    
    import simplejson
    
    def my_fn(args):
      return simplejson.dumps({'args': args})
    

All you want to test is that the function my_fn makes the correct call to
simplejson.dumps(), so you mock simplejson. You don't really care if the
object passed to simplejson is converted to json correctly as testing that is
in the scope of the simplejson module (which has it's own set of tests that
you can run if you're so inclined).

    
    
    import working_code
    import mock
    
    @mock.patch('working_code.simplejson')
    def test_my_fn(mock_simplejson):
        working_code.my_fn('test-args')
        mock_simplejson.dumps.assert_called_with({'args': 'test-args'})
    

Note that mock.patch is simply a nice way to inject and remove mocks for a
particular test. After test_my_fn is run, working_code.simplejson returned to
the state before the function was called. If that's confusing, you can think
of the test example as:

    
    
    import working_code
    import mock
    
    def test_my_fn():
        mock_simplejson = mock.Mock()
        working_code.simplejson = mock_simplejson
        working_code.my_fn('test-args')
        mock_simplejson.dumps.assert_called_with({'args': 'test-args'})
    

