我正在尝试使用 Mockito 2 模拟最终的 java class,class 正在被模拟,但我仍然得到未完成的 Stubbing 异常
I am trying to mock a final java class using Mockito 2, class is getting mocked but I still get Unfinished Stubbing Exception
我也包含了 MockMaker 文件- src\test\resources\mockito-extensions\org.mockito.plugins.MockMaker
相关代码如图所示,其中SignatureValidator为final class-
mockValidator = mock(org.opensaml.xmlsec.signature.support.SignatureValidator.class);
mockSignature = mock(SignatureImpl.class);
mockCredential = mock(org.opensaml.security.credential.Credential.class);
@Test(expected = SamlSecurityException.class)
public void testGivenGoodProfileButInvalidSignature() throws SignatureException {
when(mockSamlToken.getSignature()).thenReturn(mockSignature);
when(mockSamlToken.getSAMLIssuerName()).thenReturn("fakeIssuerName");
doThrow(SignatureException.class).when(mockValidator).validate(mockSignature,mockCredential); // getting exception for this line
validator.validate(mockSamlToken);
}
堆栈跟踪-
java.lang.Exception: Unexpected exception, expected<com.cerner.cto.security.saml.SamlSecurityException> but was<org.mockito.exceptions.misusing.UnfinishedStubbingException>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:53)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.cerner.cto.security.saml.opensaml.SignatureValidatorTest.testGivenGoodProfileButInvalidSignature(SignatureValidatorTest.java:84)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
at org.opensaml.xmlsec.signature.impl.SignatureImpl.getXMLSignature(SignatureImpl.java:153)
SignatureValidator.validate(...)
是静态方法,不是实例方法;所以有问题的陈述:
doThrow(SignatureException.class).when(mockValidator).validate(mockSignature,mockCredential);
相当于:
doThrow(SignatureException.class).when(mockValidator);
SignatureValidator.validate(mockSignature,mockCredential);
我想你能明白为什么会这样 "unfinished stubbing"。
(不幸的是 Java 甚至让你写 <i>instance</i>.<i>staticMethod</i>(... )
而不是 <i>ClassName</i>.<i>staticMethod</i>(...)
, 因为前者太误导了。一些编译器会警告你这一点。)
有关如何模拟静态方法的信息,请参阅此 Stack Overflow 问题:Mocking static methods with Mockito。
我也包含了 MockMaker 文件- src\test\resources\mockito-extensions\org.mockito.plugins.MockMaker
相关代码如图所示,其中SignatureValidator为final class-
mockValidator = mock(org.opensaml.xmlsec.signature.support.SignatureValidator.class);
mockSignature = mock(SignatureImpl.class);
mockCredential = mock(org.opensaml.security.credential.Credential.class);
@Test(expected = SamlSecurityException.class)
public void testGivenGoodProfileButInvalidSignature() throws SignatureException {
when(mockSamlToken.getSignature()).thenReturn(mockSignature);
when(mockSamlToken.getSAMLIssuerName()).thenReturn("fakeIssuerName");
doThrow(SignatureException.class).when(mockValidator).validate(mockSignature,mockCredential); // getting exception for this line
validator.validate(mockSamlToken);
}
堆栈跟踪-
java.lang.Exception: Unexpected exception, expected<com.cerner.cto.security.saml.SamlSecurityException> but was<org.mockito.exceptions.misusing.UnfinishedStubbingException>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:53)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.cerner.cto.security.saml.opensaml.SignatureValidatorTest.testGivenGoodProfileButInvalidSignature(SignatureValidatorTest.java:84)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
at org.opensaml.xmlsec.signature.impl.SignatureImpl.getXMLSignature(SignatureImpl.java:153)
SignatureValidator.validate(...)
是静态方法,不是实例方法;所以有问题的陈述:
doThrow(SignatureException.class).when(mockValidator).validate(mockSignature,mockCredential);
相当于:
doThrow(SignatureException.class).when(mockValidator);
SignatureValidator.validate(mockSignature,mockCredential);
我想你能明白为什么会这样 "unfinished stubbing"。
(不幸的是 Java 甚至让你写 <i>instance</i>.<i>staticMethod</i>(... )
而不是 <i>ClassName</i>.<i>staticMethod</i>(...)
, 因为前者太误导了。一些编译器会警告你这一点。)
有关如何模拟静态方法的信息,请参阅此 Stack Overflow 问题:Mocking static methods with Mockito。