2

I'm trying to figure out how to create unit tests for a function, which behavior is based on a third party service.

Suppose a function like this:

def sync_check():
 delta_secs = 90
 now = datetime.datetime.now().utcnow()
 res = requests.get('<third_party_service_url>')
 alert = SlackAlert()
 last_value = res[-1]['date'] # Last element of the array is the most recent
 secs = (now - last_value).seconds
 if secs >= delta_secs:
 alert.notify("out of sync. Delay: {} seconds".format(secs))
 else:
 alert.notify('in sync')

What's best practice to write unit test for this function? I need to test both if and else branches, but this depends on the third party service.

The first thing that come to my mind is to create a fake webserver and point to that one (changing url) but this way the codebase would include testing logic, like:

if test:
 url = <mock_web_server_url>
else:
 url = <third_party_service_url>

But this would change my code base. Moreover, unit testing would trigger slack alerts, which doesn't have to happen.

So there I should change again the codebase like:

if secs >= delta_secs:
 if test:
 logging.debug("out of sync alert sent - testing mode")
 else:
 alert.notify("out of sync. Delay: {} seconds".format(secs))
else:
 if test:
 logging.debug("in sync alert sent - testing mode")
 else:
 alert.notify('in sync')

Which I don't really like.

Am I missing any design to solve this problem?

asked Mar 20, 2019 at 13:33
1
  • are you familiar with Test doubles? Commented Mar 20, 2019 at 15:11

1 Answer 1

7

The usual approach here is to create a "mock" for the third party service.

So:

  1. Create a class that wraps the third party service and provides the minimal necessary API. From this point on, all interactions with the third party service must go through that class.
  2. Then create a local class that implements that same API but returns predictable, controllable results
  3. The function (or class) under test then has, as a dependency, a member which you will set to be the real third party service wrapper in production, and the mock object when testing
answered Mar 20, 2019 at 14:02
2
  • I was going to reference Chapter 15 of Working Effectively with Legacy Code, but I think your explanation is much more clear. Commented Mar 20, 2019 at 14:07
  • @JETM Haha, take THAT, Michael Feathers! Commented Mar 20, 2019 at 14:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.