Previous topic

Classes and Exceptions

Next topic

Tests for StoryMapping

This Page

Tests for StoryAPIΒΆ

This is a comprehensive set of unit tests for the kcrw.nprapi StoryAPI class. Let’s create an instance of the StoryAPI class and see how it works:

>>> from kcrw.nprapi import StoryAPI
>>> api = StoryAPI('MY_KEY')

In order to make this a properly isolated unit test, we need to isolate our code from the NPR API itself. Fortunately, we have a mock url opener we can use for this purpose:

>>> from kcrw.nprapi.mocks import MockNPROpener
>>> api.opener = opener = MockNPROpener()

Now we can make requests without worrying about connecting to the NPR service. Let’s look at the URL that was generated by the query method, by looking at our custom opener:

>>> result = api.query(1)
>>> opener.last_url
'http://api.npr.org/query?apiKey=MY_KEY&id=1'

Note that the url was constructed to include the id and the api_key. Let’s take a look at what happens when we pass strings or lists as our id:

>>> result = api.query('1')
>>> opener.last_url
'http://api.npr.org/query?apiKey=MY_KEY&id=1'
>>> result = api.query([1,2,'3'])
>>> opener.last_url
'http://api.npr.org/query?apiKey=MY_KEY&id=1%2C2%2C3'

Note that the multiple ids were concatanated into a comma separated list and url quoted. There is a special optional argument called ‘fields’, which can take a list input:

>>> result = api.query(1, fields=['a','b','c'])
>>> opener.last_url
'http://api.npr.org/query?fields=a%2Cb%2Cc&apiKey=MY_KEY&id=1'

Only certain input fields are allowed, any other input will be ignored, as will any entries with a value of None:

>>> result = api.query(1, nonsense=1, startDate=None, startNum=10)
>>> opener.last_url
'http://api.npr.org/query?apiKey=MY_KEY&startNum=10&id=1'

Changing the output_format changes the url to request a different response output:

>>> api.output_format = 'JSON'
>>> result = api.query(1)
>>> opener.last_url
'http://api.npr.org/query?output=JSON&apiKey=MY_KEY&id=1'

The same is true when we create a new api instance and pass in the output_format:

>>> api = StoryAPI('MY_KEY', 'JSON')
>>> api.opener = opener
>>> result = api.query(2)
>>> opener.last_url
'http://api.npr.org/query?output=JSON&apiKey=MY_KEY&id=2'

Creating an instance with an unknown format results in an error:

>>> api = StoryAPI('MY_KEY', 'nonsense')
Traceback (most recent call last):
...
AssertionError: Invalid output format

If we make a request that results in an error response, we get an exception thrown that includes data from the XML error message:

>>> api.query('error')
Traceback (most recent call last):
...
NPRError: XXX - Some Error!!

Additionally, if the response includes a warning message the message will be logged:

>>> result = api.query('warning')

Of course the default logging is silent, so let’s add a more visible logger:

>>> import logging
>>> import sys
>>> npr_log = logging.getLogger('kcrw.nprapi')
>>> npr_log.addHandler(logging.StreamHandler(sys.stdout))
>>> result = api.query('warning')
NPR API log: MY WARNING: 1000 - You have been warned