darksky
darksky

Reputation: 21019

Mocking an object that I'm testing with unittest

I have a function vertex_set that takes a variable graph (which is a tuple of a set of edges and a set of vertices) and returns the vertices. The function is in a module called undirected_graph and is not in a class, but a regular function.

I am writing a unit tests and my test function looks like this:

def test_vertex_test(self, graph)

I am using Python 3.3.0, which contains the mock library builtin. Would I mock the graph variable in this test: graph = MagicMock() and then call the real function with this graph? Or would I just construct some graph and then pass it, and call assertEquals to check that it returned the real thing?

How would I use mocking or stubbing here? Or is it irrelevant in my example?

Upvotes: 1

Views: 222

Answers (1)

Carlos
Carlos

Reputation: 2232

As you already seem to know, unit tests are written to ensure that your code is acting as expected and designed. We do this by passing expected parameters to our functions and testing that we get a desired result. Conversely, if we pass unexpected parameters, we want to test that our function can handle them. Because of this, we run our tests in isolation; each test method should test only one feature of our application.

There are times that the functions we need to test use libraries that aren't part of our application. This breaks the isolation and can make it difficult to test the logic of our code. For example, our method makes a call to an external library (which goes through the file system, creates files, reads some others and finally returns if it was successful or not). In this extreme example, we can't control the output of this external library. This makes it difficult to test our code since we can't know what the library will return. Enter Mocking. We would Mock the call to this third party function to return what we expect it, True and False. This way, we can test that our code can handle both results without the overhead of the external library running.

Now, for the rest of your question :)

If your vertex_set is not using a third party library, the following will apply.

I'm making up how vertex_set works in order to explain how to test it.

undirected_graph.py

def vertex_set(graph):
   """Set's the vertex based on the graph passed.

      Returns set of vertices.
      Raises ValueError if graph is not a tuple of sets.
    """

Since this vertex_set can return 2 different things (set of vertices and raise ValueError), our test needs to make sure that we can get these results when appropriate.

test_undirected_graph.py

import unittest
import undirected_graph

class UndirectedGraphTestCase(unittest.testCase):
    def test_vertex_set(self):

        # Test we can set a vertex
        graph = ({1, 2}, {3, 4})
        result = undirected_graph.vertex_set(graph)
        self.assertEqual(result. {3, 4})

        # Test we can handle a negative vertex
        graph = ({1, 2}, {-3, -4})
        result = undirected_graph.vertex_set(graph)
        self.assertEqual(result, {-3, -4})

        # Test we can handle when we give an invalid graph
        graph = ()
        self.assertRaises(ValueError, undirected_graph.vertex_set, graph)

Hopefully I made clear when Mocks are needed and when they are not. If you have more questions, let me know :)

Upvotes: 1

Related Questions