-
Notifications
You must be signed in to change notification settings - Fork 31
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
@SpykBean not reset / cleared between tests #85
Comments
Hi @moreginger I'm not sure why you think spy beans are not reset between tests. They are. Here is a complete minimal demo showing that they are: import com.ninjasquad.springmockk.SpykBean
import io.mockk.every
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.stereotype.Component
@SpringBootTest(classes = [Foo::class, Bar::class])
@TestMethodOrder(OrderAnnotation::class)
class SpyTest {
@SpykBean
lateinit var foo: Foo
@Autowired
lateinit var bar: Bar
@Test
@Order(1)
fun `should greet`() {
every { foo.greet(any()) } returns "Hi JB"
assertThat(bar.sayHello()).isEqualTo("Hi JB")
}
@Test
@Order(2)
fun `should greet 2`() {
assertThat(bar.sayHello()).isEqualTo("Hello Tim!")
}
}
@Component
class Foo {
fun greet(s: String) = "Hello $s!"
}
@Component
class Bar(val foo: Foo) {
fun sayHello() = foo.greet("Tim")
} The tests should pass, showing that the spy has been reset after the first test. If you think there is a bug somewhere, please provide a complete minimal repro (inline code as above or as a zip file), and also test first that the same test using the native Mockito-based mock support coming with Spring Boot doesn't also fail. |
Well that's very interesting. I'm confident in what I've seen as the I'll try to put together a test project for this. |
OK, I think I see what the difference is. The bean I'm spying has
...then If I change the stereotype to So I think the issue is that clearing doesn't work when beans are proxied for any reason, which includes (Let me know if you still need a test case for this... I think it should be easy to adapt one of your existing cases now?) |
Hi @moreginger Yes, a test case would be nice. |
I managed to make it work using next workaround |
Hey, I had the same problem when working with FeignClient, which I suppose is similar to the Repository stereotype. Here's an example. Spring Boot Integration Test As to my understanding, the spy should have been reset between methods, but isn't. @SpringBootTest(webEnvironment = NONE)
class PingPongServiceTest(
@Autowired private val service: PingPongService
) {
@SpyBean
private lateinit var client: PingPongFeignClient
// ...rest
} Same also occurs when work with Mocks. I feel like this is not how it is supposed to work, but correct me if I'm wrong. |
Had the same problem here with version 3.1.2 and @SpykBean. In my case, the spied bean was proxied by having the @transactional annotation. The workaround also worked: @AfterEach
override fun tearDown() {
// Workaround for issue https://github.com/Ninja-Squad/springmockk/issues/85
clearMocks(AopTestUtils.getTargetObject<FindRoomsRepository>(findRoomsSpringDataRepository))
} |
In
ClearMocksTestExecutionListener.clearMocks
there is iteration through a set of beans registered withMockkCreatedBeans
. However, only@MockKBean
s are registered with this (duringMockkPostProcessor.registerMock
),@SpykBean
s are not. This means that@SpykBean
s are not reset / cleared between tests, which can cause some very hard to debug behavior.I haven't fully understood the architecture but perhaps they could be registered in
MockkPostProcessor.createSpyIfNecessary
?Note, as a workaround the injected
@SpykBean
can be cleared manually with:The text was updated successfully, but these errors were encountered: