diff --git a/mockito/invocation.py b/mockito/invocation.py index 2b7cd8c..7adb4dd 100644 --- a/mockito/invocation.py +++ b/mockito/invocation.py @@ -715,9 +715,23 @@ def verify(self) -> None: self.verification.verify(self, self.used) def check_used(self) -> None: - if not self.allow_zero_invocations and self.used < len(self.answers): + if self.allow_zero_invocations: + return + + expected_uses = len(self.answers) + if self.used >= expected_uses: + return + + if self.used == 0: raise verificationModule.VerificationError( - "\nUnused stub: %s" % self) + "\nUnused stub: %s" % self + ) + else: + raise verificationModule.VerificationError( + "\nOnly %s of %s answers were used for %s" + % (self.used, expected_uses, self) + ) + class StubbedPropertyAccess(StubbedInvocation): def ensure_mocked_object_has_attribute(self, method_name: str) -> None: diff --git a/tests/instancemethods_test.py b/tests/instancemethods_test.py index 1ff128e..665bb4a 100644 --- a/tests/instancemethods_test.py +++ b/tests/instancemethods_test.py @@ -362,9 +362,31 @@ def testFailSecondAnswerUnused(self): when(Dog).bark('Miau').thenReturn('Yep').thenReturn('Nop') rex = Dog() rex.bark('Miau') - with pytest.raises(VerificationError): + with pytest.raises(VerificationError) as exc: verifyStubbedInvocationsAreUsed(Dog) + assert str(exc.value) == ( + "\nOnly 1 of 2 answers were used for bark('Miau')" + ) + + def testFailOnlyTwoOfThreeAnswersUsed(self): + ( + when(Dog) + .bark('Miau') + .thenReturn('Yep') + .thenReturn('Nop') + .thenReturn('Nope') + ) + rex = Dog() + rex.bark('Miau') + rex.bark('Miau') + with pytest.raises(VerificationError) as exc: + verifyStubbedInvocationsAreUsed(Dog) + + assert str(exc.value) == ( + "\nOnly 2 of 3 answers were used for bark('Miau')" + ) + @pytest.mark.usefixtures('unstub') class TestImplicitVerificationsUsingExpect: