Unit testing an API wrapper
Asked Answered
H

1

6

I'm writing a Python wrapper for an authenticated RESTful API. I'm writing up my test suite right now (Also first time test-writer here) but have a few questions:

1.a) How can I make a call, but not have to hardcode credentials into the tests since I'll be throwing it on Github?

1.b) I kind of know about mocking, but have no idea how to go about it. Would this allow me to not have to call the actual service? What would be the best way to go about this?

2) What do I test for - Just ensure that my methods are passing certains items in the dictionary?

3) Any best practices I should be following here?

Hair answered 4/11, 2012 at 6:25 Comment(0)
O
7

Hey TJ if you can show me an example of one function that you are writing (code under test, not the test code) then I can give you an example test.

Generally though:

1.a You would mock the call to the external api, you are not trying to test whether their authentication mechanism, or your internet connection is working. You are just trying to test that you are calling their api with the correct signature.

1.b Mocking in Python is relatively straight forward. I generally use the mocking library written by Michael Foord. pip install mock will get you started. Then you can do things like

import unittest
from mock import call, patch
from my_module import wrapper_func

class ExternalApiTest(unittest.TestCase):

    @patch('my_module.api_func')
    def test_external_api_call(self, mocked_api_func): 

        response = wrapper_func('user', 'pass')

        self.assertTrue(mocked_api_func.called)
        self.assertEqual(
            mocked_api_func.call_args_list,
            [call('user', 'pass')]
        )
        self.assertEqual(mocked_api_func.return_value, response)

In this example we are replacing the api_func inside my_module with a mock object. The mock object records what has been done to it. It's important to remember where to patch. You don't patch the location you imported the object from. You patch it in the location that you will be using it.

  1. You test that your code is doing the correct thing with a given input. Testing pure functions (pure in the functional programming sense) is pretty simple. You assert that given a input a, this function returns output b. It gets a bit trickier when your functions have lots of side effects.

  2. If you are finding it too hard or complicated to test a certain functiob/method it can mean that it's a badly written piece of code. Try breaking it up into testable chunks and rather than passing objects into functions try to pass primitives where possible.

Orestes answered 4/11, 2012 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.