Skip to content

Commit

Permalink
Fix SpringSpy not working with DirtiesContext... (#1869)
Browse files Browse the repository at this point in the history
DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD
fixes #1790
  • Loading branch information
leonard84 authored Jan 25, 2024
1 parent ae05f3e commit 028830d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.spockframework.spring;
Expand All @@ -22,7 +21,9 @@
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import spock.lang.Specification;

import java.util.*;
Expand All @@ -36,12 +37,19 @@
*
* @author Leonard Bruenings
*/
public class SpringMockTestExecutionListener extends AbstractSpringTestExecutionListener {
public class SpringMockTestExecutionListener extends AbstractSpringTestExecutionListener implements Ordered {

public static final String MOCKED_BEANS_LIST = "org.spockframework.spring.SpringMockTestExecutionListener.MOCKED_BEANS_LIST";

private final MockUtil mockUtil = new MockUtil();

@Override
public int getOrder() {
// needs to run before the DependencyInjectionTestExecutionListener
// https://github.com/spockframework/spock/issues/1790
return 1955;
}

@Override
public void beforeTestClass(SpringTestContext testContext) throws Exception {
}
Expand All @@ -51,10 +59,14 @@ public void prepareTestInstance(SpringTestContext testContext) throws Exception
Object testInstance = testContext.getTestInstance();
if (!(testInstance instanceof Specification)) return;

injectSpies(testContext);
}

private static void injectSpies(SpringTestContext testContext) {
ApplicationContext applicationContext = testContext.getApplicationContext();
if (applicationContext.containsBean(SpockMockPostprocessor.class.getName())) {
SpockMockPostprocessor mockPostprocessor = applicationContext.getBean(SpockMockPostprocessor.class);
mockPostprocessor.injectSpies(testInstance);
mockPostprocessor.injectSpies(testContext.getTestInstance());
}
}

Expand All @@ -63,6 +75,12 @@ public void beforeTestMethod(SpringTestContext testContext) throws Exception {
Object testInstance = testContext.getTestInstance();
if (!(testInstance instanceof Specification)) return;

if (Boolean.TRUE.equals(testContext.getAttribute(
DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE))) {
// we need to reinject the spies https://github.com/spockframework/spock/issues/1790
injectSpies(testContext);
}

Specification specification = (Specification)testInstance;
ScanScopedBeans scanScopedBeans = ReflectionUtil.getAnnotationRecursive(specification.getClass(), ScanScopedBeans.class);
Set<String> scopes = scanScopedBeans == null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.spockframework.spring.mock


import org.spockframework.spring.Service1
import org.spockframework.spring.Service2
import org.spockframework.spring.SpringSpy
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import spock.lang.Issue
import spock.lang.Specification

@Issue("https://github.com/spockframework/spock/issues/1790")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@ContextConfiguration(classes = SpyMockContext)
class SpringSpyDirtiesContextSpec extends Specification {

@SpringSpy
Service2 service2

@Autowired
Service1 service1

def "default implementation is used"() {
expect:
service1.generateString() == "The quick brown fox jumps over the lazy dog."
}

def "mocking works was well"() {
when:
def result = service1.generateString()

then:
result == "Foo"
1 * service2.generateQuickBrownFox() >> "Foo"
}
}

0 comments on commit 028830d

Please sign in to comment.