TLanni
TLanni

Reputation: 340

Mocking parameters of the function using pytest

class_functions.py

#create object called some_application
#some_application is an object, and it's current session of an application
some_application=app.SessionStart()
class_functions:
    def PushScreenValue(some_application,"selectedvalue"):
        if some_application.header=="this_screen":
           some_application.send_values("selectvalue")
           some_application.selectAll()
           return True
        else:
         return False


How can I mock the parameter pytest python
test_class.py

#Here I am mocking some_application object that is sent as a parameter.I am also mocking some_application.header,some_application.send_values and some_application.selectAll

from class_functions import class_functions



@pytest.mark.parametrize("some_application,"Value",expected", [(some_application,"Value",True)])
@mock.patch("class_functions.class_functions.mock_some_application.header")
@mock.patch("class_functions.class_functions.mock_some_application.send_values")
@mock.patch("class_functions.class_functions.mock_some_application.selectAll")
def test_PushScreenValue(mock_some_application,mock_some_application_header,mock_some_application_select,selectedvalue,expected):
  
  mock_some_application_header.return_value="this_screen"
  selectedvalue="Value"
   mock_some_application_send_values(selectedvalue)  #Sends the value to the app window
   mock_some_application_selectAll() #Selects the app window
   #checks there the function is rurning expected value
   assert class_functions_object.PushScreenValue(mock_some_application,selectedvalue)==expected
     

I am not sure how can I pass these mock objects properly in the test function

Upvotes: 0

Views: 3744

Answers (1)

gold_cy
gold_cy

Reputation: 14216

First of all the class you are trying to test appears to have syntax errors. What I think it might look like is the following:

class functions:
    def PushScreenValue(self, some_application, val):
        if some_application.header=="this_screen":
            some_application.send_values(val)
            some_application.selectAll()
            return True
        else:
            return False

Now to test it, we don't need to create a bunch of patched objects. We only need one, which is for some_application since it has method calls on it. In that case we can simply use MagicMock which is just a sub-class of Mock.

As for the test, we only have two branches of logic to test, one where it returns True and one where it returns False. All that is left is for us to set up our two tests to hit each of these branches and to make assertions along the way. A possible assertion we could make when testing if the function returns True is to see if some_application does in fact call send_values with the value we are passing in. Illustrated below are the two tests which test your function and hit both logic branches.

import pytest
from unittest.mock import MagicMock

def test_pushscreen_success():
    klass = functions()
    app = MagicMock()
    app.header = "this_screen"

    screen_val = klass.PushScreenValue(app, "fizz")

    app.send_values.assert_called_with("fizz")
    app.selectAll.assert_called_once()
    assert screen_val


def test_pushscreen_fail():
    klass = functions()
    app = MagicMock()
    app.header = "foo"

    screen_val = klass.PushScreenValue(app, "fizz")
    assert screen_val is False

When I run it I get the following output:

===================================== test session starts =====================================
platform darwin -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: *******
collected 2 items                                                                             

test_foo.py ..                                                                          [100%]

====================================== 2 passed in 0.06s ======================================

Upvotes: 1

Related Questions