Skip to content
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

Ability to inject Spock mocks as Spring beans #86

Closed
chrylis opened this issue May 13, 2015 · 9 comments
Closed

Ability to inject Spock mocks as Spring beans #86

chrylis opened this issue May 13, 2015 · 9 comments

Comments

@chrylis
Copy link

chrylis commented May 13, 2015

There was an issue on the old tracker referenced in this SO question that doesn't appear to have been migrated. Essentially, for tests that require starting up a nontrivial application context, it would be extremely helpful to be able to create a Spock mock and easily register it as a Spring bean (especially when using Spring Boot for testing).

@leonard84
Copy link
Member

This is implemented by #17

@jdigger
Copy link

jdigger commented Sep 15, 2015

Using a "pure Spring" approach, this is pretty easy:

def parentAppCtx = new StaticApplicationContext()
parentAppCtx.beanFactory.registerSingleton("myBean", Mock(MyClass))
parentAppCtx.refresh()
def appCtx = new ClassPathXmlApplicationContext("spring-config.xml", parentAppCtx)

@leonard84
Copy link
Member

@jdigger although this might work, it is quite limited, since you need to reload the application context for each Spec/Feature. We have a rather costly application context and it would increase our testing time tremendously to recreate it all the time.

@jgriff
Copy link

jgriff commented Aug 8, 2016

The latest Spring Boot 1.4 Test Support goes a long way in this direction with its new @MockBean annotation. However, it is backed by Mockito.

import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import spock.lang.Specification

@ContextConfiguration // should not be required, but had to include this for Spock to startup the Spring context
@SpringBootTest
class MySpec extends Specification {
    @MockBean
    MyBean mockOfMyBean
}

Spock support has a little catching up to do with the new cool Spring Boot 1.4 testing.

@leonard84
Copy link
Member

@jgriff spock-1.1-rc1 already includes detached mock support.

In regards to @MockBean my comment above still holds AFAIK. If it is replacing beans in an already created application context it needs to recreate all beans that have dependencies on it and the context is only valid for this one class. This disables cached-context reuse between test classes which can have a serious impact on your test run times.
However, I haven't looked too deeply into the actual implementation and if they somehow got around that, then maybe we can adopt it for spock mocks as well.

@pchudzik
Copy link

pchudzik commented May 31, 2017

I don't really know how you guys do things in spock because I use groovy only for writing tests, but I've been investigating it on spring side, and I think that spring-boot-test is not ready to be plugged with different mocking framework.

I wanted to inject spock mocks using existing spring infrastructure and since it's not yet possible here is what I was able to find out, maybe it will be helpful to someone...

Class org.springframework.boot.test.mock.mockito.MockitoPostProcessor would be pretty good entry point to start. There is pretty promising method org.springframework.boot.test.mock.mockito.MockitoPostProcessor#createMock (with spies it is more complicated and I stopped searching after I tripped over this one), but classes MockDefinition and SpyDefinition are package private (for starters) and method createMock is protected final so it is impossible to override.

Based on this in order to implement you would be forced to completely mimic MockitoPostProcessor behavior and logic in order to replace two functions responsible for mock/spy creation which is far from anything good...

imho before trying to do it in spock from scratch some changes should be made in spring-boot-test itself which will allow to plugin other mocking frameworks, and then custom implementation can be introduced in spock which will use DetachableMocks without messing with whole spring infrastructure and beans creation process.

edit: I've created issue in spring-boot.

@pchudzik
Copy link

Hi as my request in spring was rejected I've decided to do something about it and as a result I've created springmock library which allows to inject spock mocks into spock spring integration tests.

More on my blog and on the project github page

@leonard84
Copy link
Member

@pchudzik nice work, I noticed you had some comments, e.g., Spock doesn't support additional interfaces for mocks yet, feel free to create some issues.

@jeffsheets
Copy link

implemented by #796 I think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants