Version: 1.4.3-RELEASE
I have two RestTemplate beans for different purpose:
@Bean
public RestTemplate basicRestTemplate() {
// config restTemplate
}
@Bean
public RestTemplate specialRestTemplate() {
// config restTemplate
}
The following component depends on the specialRestTemplate and @Autowired inject the correct bean by name:
@Autowired
public MyComponent(RestTemplate specialRestTemplate){}
But in my test, I'd like to spy on the specialRestTemplate, using @SpyBean is giving me this stacktrace:
java.lang.IllegalStateException: No bean found for definition [SpyDefinition@6e0a0baa name = '', typeToSpy = org.springframework.web.client.RestTemplate, reset = AFTER]
at org.springframework.util.Assert.state(Assert.java:392)
at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.inject(MockitoPostProcessor.java:391)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:73)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:62)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:49)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
When I debug into MockitoPostProcessor I found that registerSpy only find existing bean based on type, and when it found more than one bean, then determine the spy candidate by checking isPrimary.
So even though @SpyBean has an argument for bean name, it doesn't support get bean by name yet.
Comment From: fuesec
how did you solve this problem?
Comment From: wilkinsona
@fuesec you shouldn't need to do anything. This issue was a bug that has been fixed. If you use @SpyBean(name = "yourBean"), the spy will be created for the bean named yourBean. When there are multiple beans of the same type, this allows you to indicate which of those beans should be spied upon.