micronaut-test icon indicating copy to clipboard operation
micronaut-test copied to clipboard

Support `@SpyBean`

Open caiolopes opened this issue 3 years ago • 3 comments

Feature description

I was looking for having in the same class some mocking tests and non-mocking tests.

It would be very handy if we can support something similar to @SpyBean in Spring.

I tried to use with @MockBean without a success (got a StackOverflowError). Maybe I am doing something wrong, I am not sure.

@MicronautTest
class MyTest {
  @Inject MyService myService;

  @MockBean(MyService.class)
  public MyService spyMyService() {
    return spy(myService);
  }
  
  // ...
}

Right now my solution is having two separated test classes (one mocking the bean with @MockBean and another one not mocking it).

If there is a better workaround I would appreciate it!

caiolopes avatar Oct 16 '21 04:10 caiolopes

This indeed is what I was looking for. Can you share your workaround? I use kotest w/ kotlin but I think it'd be similar. I use coroutines and BlockingHttpClient.retrieve so I don't have stack traces but I guessing from a delay it might be StackOverFlow.

jacekgajek avatar Jan 24 '22 10:01 jacekgajek

Hi @jacekgajek my "workaround" was having two separated test classes.

  • In one test class, I use @MockBean
  • Another test class I don't mock that specific bean and let it be the real one

caiolopes avatar Feb 02 '22 12:02 caiolopes

This might be a suitable workaround until something else is implemented.

solution in kotlin as this is something we have in our own codebase and working with the kotlin mockk library.

@MicronautTest
class MyTest {
  @Inject 
  lateinit var myService: MyService;

  @Singleton
  fun spybean(): BeanCreatedEventListener<MyService> {
      return BeanCreatedEventListener<MyService> { spyk(it.bean) }
  }
  // ...
}

Edit: to get this to work from within the same test, then the injected value has to be wrapped in a BeanProvider

frehov avatar Jun 07 '22 11:06 frehov