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

Annotation to attach detached mock #779

Closed
musketyr opened this Issue Oct 5, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@musketyr

musketyr commented Oct 5, 2017

Attaching mock manually is not very practical. It would be nice if Spock has an annotation to attach detached mocks. Here's working implementation I'm using locally:

import org.spockframework.runtime.extension.ExtensionAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@ExtensionAnnotation(DetachedExtension.class)
public @interface Detached { }
import org.spockframework.mock.MockUtil;
import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension;
import org.spockframework.runtime.extension.IMethodInterceptor;
import org.spockframework.runtime.extension.IMethodInvocation;
import org.spockframework.runtime.model.FieldInfo;
import spock.lang.Specification;

public class DetachedExtension extends AbstractAnnotationDrivenExtension<Detached> {

    private static final MockUtil MOCK_UTIL = new MockUtil();

    @Override
    public void visitFieldAnnotation(Detached annotation, FieldInfo field) {
        field.getParent().addSetupInterceptor(new IMethodInterceptor() {
            @Override
            public void intercept(IMethodInvocation invocation) throws Throwable {
                MOCK_UTIL.attachMock(field.readValue(invocation.getInstance()), (Specification) invocation.getInstance());
                invocation.proceed();
            }
        });
        field.getParent().addCleanupInterceptor(new IMethodInterceptor() {
            @Override
            public void intercept(IMethodInvocation invocation) throws Throwable {
                MOCK_UTIL.detachMock(field.readValue(invocation.getInstance()));
                invocation.proceed();
            }
        });
    }
}

Which can be used for example within Grails Unit Tests using AutowiredTest annotation:

@Autowired @Detached FooService fooService
@leonard84

This comment has been minimized.

Show comment
Hide comment
@leonard84

leonard84 Oct 5, 2017

Member

Spocks org.spockframework.spring.SpringMockTestExecutionListenerautomatically attaches detached mocks it should be automatically registered by spocks SpringExtension. Did you include the spock-spring module?

Member

leonard84 commented Oct 5, 2017

Spocks org.spockframework.spring.SpringMockTestExecutionListenerautomatically attaches detached mocks it should be automatically registered by spocks SpringExtension. Did you include the spock-spring module?

@musketyr

This comment has been minimized.

Show comment
Hide comment
@musketyr

musketyr Oct 5, 2017

Grails unit tests are not recognized as Spring tests but I guess there might be other use cases (e.g TCK also providing mocks for implementations).

see https://medium.com/@musketyr/leveraging-spock-spring-module-in-grails-unit-tests-e839340de272 for context.

musketyr commented Oct 5, 2017

Grails unit tests are not recognized as Spring tests but I guess there might be other use cases (e.g TCK also providing mocks for implementations).

see https://medium.com/@musketyr/leveraging-spock-spring-module-in-grails-unit-tests-e839340de272 for context.

@musketyr

This comment has been minimized.

Show comment
Hide comment
@musketyr

musketyr Oct 5, 2017

Generally speaking as DetachedMockFactory is part of the Spock core library it should be possible to use it in a simple way even without Spring module.

musketyr commented Oct 5, 2017

Generally speaking as DetachedMockFactory is part of the Spock core library it should be possible to use it in a simple way even without Spring module.

@leonard84

This comment has been minimized.

Show comment
Hide comment
@leonard84

leonard84 Nov 15, 2017

Member

Implemented with #790 the annotation is called @AutoAttach, thanks for your input.

Member

leonard84 commented Nov 15, 2017

Implemented with #790 the annotation is called @AutoAttach, thanks for your input.

@leonard84 leonard84 closed this Nov 15, 2017

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