02 Intermediate Python: OOP, Types, Errors & Testing/2.14 Lab code (reference solutions)/2.14.5 lab/tests/test_library.py
§ 2.14.5section 19 of 20·~9 min
lab/tests/test_library.py
import pytest
from library import Book, BookNotAvailableError, Library, Member
from library.storage import load, save
@pytest.fixture
def lib() -> Library:
lib = Library()
lib.add_book(Book("1", "Wings of Fire", "A.P.J. Abdul Kalam"))
lib.add_book(Book("2", "The White Tiger", "Aravind Adiga"))
lib.add_book(Book("3", "Godan", "Munshi Premchand"))
lib.add_book(Book("4", "Train to Pakistan", "Khushwant Singh"))
lib.add_member(Member("M1", "Asha"))
lib.add_member(Member("M2", "Vikram"))
return lib
def test_issue_marks_book_unavailable(lib):
lib.issue_book("1", "M1")
assert not lib.books["1"].available
assert lib.members["M1"].borrowed == ["1"]
def test_issue_twice_raises(lib):
lib.issue_book("1", "M1")
with pytest.raises(BookNotAvailableError):
lib.issue_book("1", "M2")
def test_return_makes_available(lib):
lib.issue_book("1", "M1")
lib.return_book("1")
assert lib.books["1"].available
assert lib.members["M1"].borrowed == []
def test_return_unissued_raises(lib):
with pytest.raises(ValueError):
lib.return_book("2")
def test_member_limit(lib):
for isbn in ["1", "2", "3"]:
lib.issue_book(isbn, "M1")
with pytest.raises(ValueError):
lib.issue_book("4", "M1")
def test_duplicate_isbn_rejected(lib):
with pytest.raises(ValueError):
lib.add_book(Book("1", "Copy", "Someone"))
@pytest.mark.parametrize("query, expected", [("wings", 1), ("PREMCHAND", 1), ("tiger", 1), ("zzz", 0)])
def test_search(lib, query, expected):
assert len(lib.search(query)) == expected
def test_save_and_load_roundtrip(lib, tmp_path):
lib.issue_book("2", "M2")
path = tmp_path / "library.json"
save(lib, path)
restored = load(path)
assert restored.books["2"].issued_to == "M2"
assert restored.members["M2"].borrowed == ["2"]