Pytest模拟在循环中对同一函数的不同行为

huangapple go评论70阅读模式
英文:

Pytest mock different behaviour to same function on loop

问题

I'm having troubles on mocking the return value on looped lists. Imagine I have a function that paints the cars like this:

def do_operate(car_list: list):
    flawless_car_list = list()
    for car in car_list:
        if paint_the_car(car):
            flawless_car_list.append(car)
        else:
            print_log(f"{car} couldn't get painted")

    return flawless_car_list

On each iteration there's a some random error probability (like unable to connect to server, or couldn't get car details) that a car couldn't get painted for an unknown reason. We have tests to ensure that even a car can't get painted, we are continuing to paint the rest of the upcoming cars, and logging the erroneous cars.

If I test the happy path, everything is ok like this:

def test_happy_path(mocker):
    test_list = ["honda", "bmw", "ford"]
    mocker.patch("pytest1.paint_the_car", return_value=True)
    mocker.patch("pytest1.print_log")

    card_list = do_operate(car_list=test_list)

    assert len(card_list) == 3
    paint_the_car.assert_called()
    print_log.assert_not_called()

But at some point I need to be able to mock the paint_car like this mocker.patch("pytest1.paint_the_car", return_value=False) for a specific car (second car) and mocker.patch("pytest1.paint_the_car", return_value=True) for first and third cars. In the end, I would like to pass the assertions;

def test_error_occured_on second_item(mocker):
    test_list = ["honda", "bmw", "ford"]

    # HOW TO CHANGE MOCKS?
    mocker.patch("pytest1.paint_the_car", return_value=True)
    mocker.patch("pytest1.print_log")

    card_list = do_operate(car_list=test_list)

    assert len(card_list) == 2
    paint_the_car.assert_called()
    print_log.assert_called_with("bmw couldn't get painted")
英文:

I'm having troubles on mocking the return value on looped lists. Imagine I have a function that paints the cars like this:

def do_operate(car_list: list):
    flawless_car_list = list()
    for car in car_list:
        if paint_the_car(car):
            flawless_car_list.append(car)
        else:
            print_log(f"{car} couldn't get painted")

    return flawless_car_list

On each iteration there's a some random error probability (like unable to connect to server, or couldn't get car details) that a car couldn't get painted for an unknown reason. We have tests to ensure that even a car can't get painted, we are continuing to paint the rest of the upcoming cars, and logging the erroneous cars.

If I test the happy path, everything is ok like this:

def test_happy_path(mocker):
    test_list = ["honda", "bmw", "ford"]
    mocker.patch("pytest1.paint_the_car", return_value=True)
    mocker.patch("pytest1.print_log")

    card_list = do_operate(car_list=test_list)

    assert len(card_list) == 3
    paint_the_car.assert_called()
    print_log.assert_not_called()

But at some point I need to be able to mock the paint_car like this mocker.patch("pytest1.paint_the_car", return_value=False) for a specific car (second car) and mocker.patch("pytest1.paint_the_car", return_value=True) for first and third cars. In the end, I would like to pass the assertions;

def test_error_occured_on_second_item(mocker):
    test_list = ["honda", "bmw", "ford"]

    # HOW TO CHANGE MOCKS?
    mocker.patch("pytest1.paint_the_car", return_value=True)
    mocker.patch("pytest1.print_log")

    card_list = do_operate(car_list=test_list)

    assert len(card_list) == 2
    paint_the_car.assert_called()
    print_log.assert_called_with("bmw couldn't get painted")

答案1

得分: 2

你可以像这样使用side_effect与返回值列表:mocker.patch("pytest1.paint_the_car", side_effect=[True, False, True]),然后它会在第一次和第三次调用时返回True,在第二次调用时返回False

请参阅官方文档中的side effect

英文:

You can use side_effect with a list of return values like so: mocker.patch("pytest1.paint_the_car", side_effect = [True, False, True]) then it would return True for the first and 3rd calls, and False for the second call.

See official docs for side effect.

huangapple
  • 本文由 发表于 2023年2月24日 17:08:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定