My Adventures in Coding

February 26, 2011

Python – Getting Started with Python Mock

Filed under: Python,Testing — Brian @ 12:00 am
Tags: , , ,

These examples all use the Python Mock library. This post is just a quick “Getting Started” for someone who is new to using the Python Mock library, once you get started refer to the Python Mock Documentation.

First you will need to install the mock library:

pip install -U mock

Your test file will need the following import statement:

from mock import patch, Mock

To mock a method in a class to return a specific value use @patch.object.

@patch.object(my_module.MyClass, 'my_method')
def test_my_method_shouldReturnTrue_whenMyMethodReturnsSomeValue(self, mock_my_method):
    mock_my_method.return_value=True
    some_other_class =  SomeOtherClassThatUsesMyClass()
    result = some_other_class.method_under_test()
    self.assertTrue(result)

To mock a method in a class with @patch.object but return a different value each time it is called, use side_effect. Side effect allows you to define a custom method and have that method called each time your mock method is called. The value returned from this method will be used as the return value your mock method.

@patch.object(my_module.MyClass, 'my_method')
def test_my_method_shouldReturnMultipleValues_whenMyMethodReturnsSomeValue(self, mock_my_method):
    list_of_return_values= [True,False,False]
    def side_effect():
        return list_of_return_values.pop()
    mock_my_method.side_effect = side_effect
    some_other_class =  SomeOtherClassThatUsesMyClass()
    self.assertFalse(some_other_class.method_under_test())
    self.assertFalse(some_other_class.method_under_test())
    self.assertTrue(some_other_class.method_under_test())

To mock an entire class to test interactions with that class use @patch.

@patch('my_module.MyClass')
def test_my_method_shouldCallMyClassMethodMyMethod_whenSomeOtherClassMethodIsCalled(self, mock_my_class):
    some_other_class =  SomeOtherClassThatUsesMyClass()
    some_other_class.method_under_test()
    self.assertTrue(mock_my_class.called)

To mock an entire class with @patch and still set the return value of a method in that class, grab the instance of the mock object’s return value and set the method’s return value on the instance. There is a section on the patch page explaining how to do this.

@patch('my_module.MyClass')
def test_my_method_shouldReturnTrue_whenSomeOtherClassMethodIsCalledAndAReturnValueIsSet(self, mock_my_class):
    mc = mock_my_class.return_value
    mc.my_method.return_value = True
    some_other_class =  SomeOtherClassThatUsesMyClass()
    result = some_other_class.method_under_test()
    self.assertTrue(result)

Finally, here is the simple code I used as my “code under test” to write these example tests:

class MyClass():
    def my_method(self):
        pass

class SomeOtherClassThatUsesMyClass():
    def method_under_test(self):
        myclass = MyClass()
        return myclass.my_method()

There are many other features in the Python Mock library, but these are the basics that will help you get started!

March 5, 2008

TDD

Filed under: SD West 2008,Testing — Brian @ 8:12 pm
Tags:

During the talk on TDD (Test Driven Development) the loop of the TDD cycle was discussed. I realize some of you who have already read about this topic and are familiar with this cycle, but I just thought I would mention it.

The TDD Loop

  1. Write a small test for new functionality
  2. Write just enough code for the new functionality to pass the test
  3. Confirm that the revised system passes all tests
  4. Refactor to remove “code smells”
  5. Confirm that the revised system still passes all tests

So the question came up during the talk “How do you know how many tests to write?”. The answer to this question was “Write as many tests as you feel are necessary to feel confident that the code functions as it is supposed to”. Developers are very good at writing positive tests (tests that show the code does what it is supposed to), however developers need to learn to get into the mindset of writing negative tests (tests that exercise conditions that should not happen but might).

TDD is extremely useful and important. Part of the problem pointed out with adoption is that if developers are just told to write unit tests and use TDD but are never given a good explanation of “Why” it can cause resistance to moving in this direction.

Unit Testing Private Methods?

Filed under: Testing — Brian @ 8:05 pm
Tags: ,

There was a section of a lecture I attended by Robert C. Martin devoted to unit testing and the topic of writing unit tests for private methods was mentioned. So the question was “Should you write unit tests for private methods” and the answer was NO.

A class has an interface of public methods. Those public methods use private methods. You write test cases for the public methods to ensure all functionality the class provides is covered by tests. If you need to write unit tests specifically for the private methods, then your test cases for the public methods are probably not covering all cases, and if they do, then the tests for the private methods are just duplicates of the public method test cases. One of the main problems with unit tests on private methods is that they make it difficult to refactor the inner workings of a class.

A developer should have the freedom to refactor the code within a class without needing to re-write existing unit tests. We should be working at removing obstacles to refactoring and creating meaningful interfaces to our code that are both straight forward for development and testing. If you absolutely feel a private method in a class is complicated enough that it warrants being unit tested on it’s own, then perhaps that is functionality that should be broken out into it’s own class.

The public methods of a class are an interface. One job of unit tests is to explain the correct usage of a class to the next developer who uses it. Trying to unit test the private methods of a class will just make it more difficult for other developers to understand.

Unit Testing

Filed under: SD West 2008,Testing — Brian @ 7:56 pm

Part of the afternoon talk was on unit testing. There was a lot of material covered, so here are just a few topics discussed.

  • Always remember that when you are adding unit tests you are adding more code that will now need to be maintained. Writing difficult to understand or brittle unit tests will cause future maintenance problems.
  • Unit tests must be highly readable so that they will be easier for developers to understand in the future as they are also a form of documentation. Reading existing unit tests are also a great way for a developer to quickly understand how an existing class is supposed to be used.
  • Never have a conditional or loop in a unit test, if you do, you must rewrite the test.
  • Unit tests should always be simple.
  • Unit tests are extremely important. TDD is important, but if there is an area of an application that is not currently covered by unit tests there is still a great deal of value in adding unit tests to these areas of the application

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.