Why using yield instead of return in pytest fixtures?

1.1k views Asked by At

I see why using yield keyword when we want to run our tests and then clean things up going back to the fixture and running some code after the yield statement. As the code below.

@pytest.fixture
def sending_user(mail_admin):
    user = mail_admin.create_user()
    yield user
    mail_admin.delete_user(user)

However why is it necessary to use yield when we only want to return an object and don't comeback to the fixture, returning a patch for example?

from unittest.mock import patch, mock_open
from pytest import raises, fixture
import os.path

def read_from_file(file_path):
    if not os.path.exists(file_path):
        raise Exception("File does not exists!")
    with open(file_path, "r") as f:
        return f.read().splitlines()[0]

@fixture()
def mock_open_file():
    with patch("builtins.open", new_callable=mock_open, read_data="Correct string") as mocked:
        yield mocked #instead of: return mocked

@fixture()
def mock_os():
    with patch("os.path.exists", return_value=True) as mocked:
        yield mocked #instead of: return mocked

def test_read_file_and_returns_the_correct_string_with_one_line(mock_os, mock_open_file):
    result = read_from_file("xyz")
    mock_open_file.assert_called_once_with("xyz", "r")
    assert result == "Correct string"

def test_throws_exception_when_file_doesnt_exist(mock_os, mock_open_file):
    mock_os.return_value = False
    with raises(Exception):
        read_from_file("xyz")
0

There are 0 answers