-
-
Notifications
You must be signed in to change notification settings - Fork 149
Add spy_return_iter
attribute to spy
#524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution @vokracko!
Left some minor comments, please take a look.
tests/test_pytest_mock.py
Outdated
assert spy.spy_return is not None | ||
assert spy.spy_return_iter is not None | ||
assert list(spy.spy_return_iter) == result | ||
assert spy.spy_return_list == [ANY] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work?
assert spy.spy_return_list == [ANY] | |
assert isinstance(spy.spy_return_list[0], Iterator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in e6c26b2
def test_spy_return_iter_unset_in_last_call(mocker: MockerFixture) -> None: | ||
class Foo: | ||
iterables = [ | ||
(i for i in range(3)), | ||
[3, 4, 5], | ||
] | ||
|
||
def bar(self) -> Iterable[int]: | ||
return self.iterables.pop(0) | ||
|
||
foo = Foo() | ||
spy = mocker.spy(foo, "bar") | ||
result_iterator = list(foo.bar()) | ||
|
||
assert result_iterator == [0, 1, 2] | ||
assert list(spy.spy_return_iter) == result_iterator | ||
|
||
result_iterable = foo.bar() | ||
assert result_iterable == [3, 4, 5] | ||
assert spy.spy_return_iter is None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion to make this clearer:
def test_spy_return_iter_unset_in_last_call(mocker: MockerFixture) -> None: | |
class Foo: | |
iterables = [ | |
(i for i in range(3)), | |
[3, 4, 5], | |
] | |
def bar(self) -> Iterable[int]: | |
return self.iterables.pop(0) | |
foo = Foo() | |
spy = mocker.spy(foo, "bar") | |
result_iterator = list(foo.bar()) | |
assert result_iterator == [0, 1, 2] | |
assert list(spy.spy_return_iter) == result_iterator | |
result_iterable = foo.bar() | |
assert result_iterable == [3, 4, 5] | |
assert spy.spy_return_iter is None | |
def test_spy_return_iter_resets(mocker: MockerFixture) -> None: | |
class Foo: | |
iterables = [ | |
(i for i in range(3)), | |
99, | |
] | |
def bar(self) -> Iterable[int]: | |
return self.iterables.pop(0) | |
foo = Foo() | |
spy = mocker.spy(foo, "bar") | |
result_iterator = list(foo.bar()) | |
assert result_iterator == [0, 1, 2] | |
assert list(spy.spy_return_iter) == result_iterator | |
assert foo.bar() == 99 | |
assert spy.spy_return_iter is None |
Mixing iterator and iterables on this test is not necessary for the logic and adds a small bit of confusion.
Co-authored-by: Bruno Oliveira <[email protected]>
Recently I've run into situation where I wanted to
spy
on a method returningIterator
.That wasn't possible because the iterator is already consumed by the time you try to assert it.
In this PR I add a new attribute,
spy_return_iter
storing a duplicate of the returned iterator (leveragingitertools.tee
).