Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there a preferred way to test callbacks with pytest?

I am unable to find specific examples for testing callbacks using pytest in the docs, google, or here on SO. I found this: What is the right way to test callback invocation using Python unittest?; but it's for unittest. I'm guessing that the monkeypatch functionality of pytest is where I should look but I'm new to automated testing and am looking for an example.

def foo(callback):
    callback('Buzz', 'Lightyear')

#--- pytest code ----
def test_foo():
    foo(hello)
    # how do I test that hello was called?
    # how do I test that it was passed the expected arguments?

def hello(first, last):
    return "hello %s %s" % first, last

Thank you in advance.

like image 347
guyja Avatar asked Apr 04 '14 13:04

guyja


People also ask

Why pytest is better than unittest?

Pytest has rich inbuilt features which require less piece of code compared to unittest. In the case of unittest, we have to import a module, create a class and then define testing functions inside the class. But in the case of pytest, we have to define the functions and assert the conditions inside them.

Can I use unittest with pytest?

pytest supports running Python unittest -based tests out of the box. It's meant for leveraging existing unittest -based test suites to use pytest as a test runner and also allow to incrementally adapt the test suite to take full advantage of pytest's features.

Is pytest a test runner?

Pytest PyCharm supports pytest, a fully functional testing framework. The following features are available: The dedicated test runner.


2 Answers

The idea is still the same.

You need to replace hello() function with a Mock, or, in another words, to "mock" the function.

Then you can use assert_called_with() to check that it was called with specific arguments you need.

like image 136
alecxe Avatar answered Sep 19 '22 09:09

alecxe


Here is my working code after applying the answer supplied by @alecxe.

def foo(callback):
    callback('Buzz', 'Lightyear')

#--- pytest code ---

import mock

def test_foo():
    func = mock.Mock()

    # pass the mocked function as the callback to foo
    foo(func)

    # test that func was called with the correct arguments
    func.assert_called_with('Buzz', 'Lightyear')

Thank you.

like image 44
guyja Avatar answered Sep 20 '22 09:09

guyja