2

I'm working on writing some tests for a python app with the pytest framework. I have a problem in one of the tests, which I'm not sure the way it works.

example:

@pytest.mark.parametrize("result, status, xml_err, xml_status",[
        ("PASS",True,False,"XML_ERROR"),
        ("Validation error", False, False, "XML_ERROR")
    ])
def test_xml_build_neg(self, monkeypatch,result, status, xml_err, xml_status):

    def validate(self):
        return status, result, {}

    def transform(self, v_dict):
        return "<xml/>", 50.0, xml_status, xml_err



    monkeypatch.setattr(DataValidator, "validate", validate)
    monkeypatch.setattr(XMLTransformer, "transform", transform)


    o_result, o_status, o_xml_err, o_xml_status= XMLOutputBuilder().build(ExtractionResult(), "test", b"test")

    assert o_result == result, "Validation results not matching"
    assert o_status == status, "Validation Status not matching"
    .....

I did monkeypatch for some methods inside my XMLOutputBuilder to test some error scenarios. I expected my mock methods would return the values based on the incoming parameters, but it did not. I understand the behaviour is because the mocks and fixtures are loaded only once and it cannot be changed further (Correct me If I'm wrong).

Is there any other methods to make this scenario work ? Or I have to write separate test methods for the parameters?

Kris
  • 8,680
  • 4
  • 39
  • 67

1 Answers1

0

I'm unable to recreate the problem. Maybe a different code path is executed than what the monkeypatch attributes are set for.

In the below minimal example I added some of the complexity in your example: A class A in module a.py with the validate function to be patched:

class A:
    def validate(self):
        status, result = "not", "patched"
        return status, result

A class B in module b.py using functionality from class A in module a.py:

import a
class B():

    def build(self):
        return a.A().validate()

A test module test.py:

import pytest
from a import A
from b import B

@pytest.mark.parametrize("arg1, arg2", [("foo1", "bar1"), ("foo2", "bar2")])
def test_monkeypatch_with_params(monkeypatch, arg1, arg2):

    def validate(self):
        print(arg1, arg2)
        return arg1, arg2

    monkeypatch.setattr(A, "validate", validate)

    actual_status, actual_result = B().build()
    assert actual_status == arg1
    assert actual_result == arg2

executed as:

pytest test.py -s 
m. bron
  • 518
  • 1
  • 9
  • 11