Inherit enclosing class's configuration in nested tests

Fixes gh-12470
This commit is contained in:
Andy Wilkinson 2020-10-28 07:03:39 +00:00
parent b0a1c2a740
commit 6b437ece54
11 changed files with 171 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,12 +21,12 @@ import java.util.List;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
/** /**
* {@link ContextCustomizerFactory} to support * {@link ContextCustomizerFactory} to support
@ -39,8 +39,9 @@ class OverrideAutoConfigurationContextCustomizerFactory implements ContextCustom
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configurationAttributes) { List<ContextConfigurationAttributes> configurationAttributes) {
boolean enabled = MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY) AnnotationDescriptor<OverrideAutoConfiguration> descriptor = TestContextAnnotationUtils
.get(OverrideAutoConfiguration.class).getValue("enabled", Boolean.class).orElse(true); .findAnnotationDescriptor(testClass, OverrideAutoConfiguration.class);
boolean enabled = (descriptor != null) ? descriptor.getAnnotation().enabled() : true;
return !enabled ? new DisableAutoConfigurationContextCustomizer() : null; return !enabled ? new DisableAutoConfigurationContextCustomizer() : null;
} }

View File

@ -20,12 +20,11 @@ import java.util.List;
import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
/** /**
* {@link ContextCustomizerFactory} that globally disables metrics export unless * {@link ContextCustomizerFactory} that globally disables metrics export unless
@ -38,8 +37,8 @@ class MetricsExportContextCustomizerFactory implements ContextCustomizerFactory
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) { List<ContextConfigurationAttributes> configAttributes) {
boolean disableMetricsExport = !MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY) boolean disableMetricsExport = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
.get(AutoConfigureMetrics.class).isPresent(); AutoConfigureMetrics.class) == null;
return disableMetricsExport ? new DisableMetricExportContextCustomizer() : null; return disableMetricsExport ? new DisableMetricExportContextCustomizer() : null;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,10 +22,11 @@ import java.util.List;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -41,9 +42,11 @@ class ImportsContextCustomizerFactory implements ContextCustomizerFactory {
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) { List<ContextConfigurationAttributes> configAttributes) {
if (MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY).isPresent(Import.class)) { AnnotationDescriptor<Import> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
assertHasNoBeanMethods(testClass); Import.class);
return new ImportsContextCustomizer(testClass); if (descriptor != null) {
assertHasNoBeanMethods(descriptor.getRootDeclaringClass());
return new ImportsContextCustomizer(descriptor.getRootDeclaringClass());
} }
return null; return null;
} }

View File

@ -46,6 +46,8 @@ import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.ContextLoader; import org.springframework.test.context.ContextLoader;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContext; import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import org.springframework.test.context.TestContextBootstrapper; import org.springframework.test.context.TestContextBootstrapper;
import org.springframework.test.context.TestExecutionListener; import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.DefaultTestContextBootstrapper; import org.springframework.test.context.support.DefaultTestContextBootstrapper;
@ -318,8 +320,12 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
} }
protected SpringBootTest getAnnotation(Class<?> testClass) { protected SpringBootTest getAnnotation(Class<?> testClass) {
return MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS).get(SpringBootTest.class) AnnotationDescriptor<SpringBootTest> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
.synthesize(MergedAnnotation::isPresent).orElse(null); SpringBootTest.class);
if (descriptor != null) {
return descriptor.getAnnotation();
}
return null;
} }
protected void verifyConfiguration(Class<?> testClass) { protected void verifyConfiguration(Class<?> testClass) {

View File

@ -18,9 +18,10 @@ package org.springframework.boot.test.context;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
/** /**
* {@link ContextCustomizer} to track the web environment that is used in a * {@link ContextCustomizer} to track the web environment that is used in a
@ -35,8 +36,9 @@ class SpringBootTestWebEnvironment implements ContextCustomizer {
private final WebEnvironment webEnvironment; private final WebEnvironment webEnvironment;
SpringBootTestWebEnvironment(Class<?> testClass) { SpringBootTestWebEnvironment(Class<?> testClass) {
this.webEnvironment = MergedAnnotations.from(testClass, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY) AnnotationDescriptor<SpringBootTest> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
.get(SpringBootTest.class).getValue("webEnvironment", WebEnvironment.class).orElse(null); SpringBootTest.class);
this.webEnvironment = (descriptor != null) ? descriptor.getAnnotation().webEnvironment() : null;
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.TestContextAnnotationUtils;
/** /**
* A {@link ContextCustomizerFactory} to add Mockito support. * A {@link ContextCustomizerFactory} to add Mockito support.
@ -35,8 +36,15 @@ class MockitoContextCustomizerFactory implements ContextCustomizerFactory {
// We gather the explicit mock definitions here since they form part of the // We gather the explicit mock definitions here since they form part of the
// MergedContextConfiguration key. Different mocks need to have a different key. // MergedContextConfiguration key. Different mocks need to have a different key.
DefinitionsParser parser = new DefinitionsParser(); DefinitionsParser parser = new DefinitionsParser();
parser.parse(testClass); parseDefinitions(testClass, parser);
return new MockitoContextCustomizer(parser.getDefinitions()); return new MockitoContextCustomizer(parser.getDefinitions());
} }
private void parseDefinitions(Class<?> testClass, DefinitionsParser parser) {
parser.parse(testClass);
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
parseDefinitions(testClass.getEnclosingClass(), parser);
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,7 +29,6 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
@ -38,11 +37,10 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
/** /**
* {@link ContextCustomizer} for {@link TestRestTemplate}. * {@link ContextCustomizer} for {@link TestRestTemplate}.
@ -55,10 +53,9 @@ class TestRestTemplateContextCustomizer implements ContextCustomizer {
@Override @Override
public void customizeContext(ConfigurableApplicationContext context, public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedContextConfiguration) { MergedContextConfiguration mergedContextConfiguration) {
MergedAnnotation<?> annotation = MergedAnnotations AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
.from(mergedContextConfiguration.getTestClass(), SearchStrategy.INHERITED_ANNOTATIONS) .findAnnotationDescriptor(mergedContextConfiguration.getTestClass(), SpringBootTest.class);
.get(SpringBootTest.class); if (springBootTest.getAnnotation().webEnvironment().isEmbedded()) {
if (annotation.getEnum("webEnvironment", WebEnvironment.class).isEmbedded()) {
registerTestRestTemplate(context); registerTestRestTemplate(context);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,11 +19,11 @@ package org.springframework.boot.test.web.client;
import java.util.List; import java.util.List;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
/** /**
* {@link ContextCustomizerFactory} for {@link TestRestTemplate}. * {@link ContextCustomizerFactory} for {@link TestRestTemplate}.
@ -36,8 +36,9 @@ class TestRestTemplateContextCustomizerFactory implements ContextCustomizerFacto
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) { List<ContextConfigurationAttributes> configAttributes) {
MergedAnnotations annotations = MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS); AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
if (annotations.isPresent(SpringBootTest.class)) { .findAnnotationDescriptor(testClass, SpringBootTest.class);
if (springBootTest != null) {
return new TestRestTemplateContextCustomizer(); return new TestRestTemplateContextCustomizer();
} }
return null; return null;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,7 +31,6 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.codec.CodecCustomizer; import org.springframework.boot.web.codec.CodecCustomizer;
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -39,11 +38,10 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.ExchangeStrategies;
@ -57,9 +55,9 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
@Override @Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
MergedAnnotation<?> annotation = MergedAnnotations AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
.from(mergedConfig.getTestClass(), SearchStrategy.INHERITED_ANNOTATIONS).get(SpringBootTest.class); .findAnnotationDescriptor(mergedConfig.getTestClass(), SpringBootTest.class);
if (annotation.getEnum("webEnvironment", WebEnvironment.class).isEmbedded()) { if (springBootTest.getAnnotation().webEnvironment().isEmbedded()) {
registerWebTestClient(context); registerWebTestClient(context);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,11 +19,11 @@ package org.springframework.boot.test.web.reactive.server;
import java.util.List; import java.util.List;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.ContextCustomizerFactory;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
@ -38,8 +38,9 @@ class WebTestClientContextCustomizerFactory implements ContextCustomizerFactory
@Override @Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) { List<ContextConfigurationAttributes> configAttributes) {
MergedAnnotations annotations = MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS); AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
if (isWebClientPresent() && annotations.isPresent(SpringBootTest.class)) { .findAnnotationDescriptor(testClass, SpringBootTest.class);
if (springBootTest != null) {
return new WebTestClientContextCustomizer(); return new WebTestClientContextCustomizer();
} }
return null; return null;

View File

@ -0,0 +1,107 @@
/*
* Copyright 2012-2020 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.springframework.boot.test.context.nestedtests;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.nestedtests.InheritedNestedTestConfigurationTests.ActionPerformer;
import org.springframework.boot.test.context.nestedtests.InheritedNestedTestConfigurationTests.AppConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* Tests for nested test configuration when the configuration is inherited from the
* enclosing class (the default behaviour).
*
* @author Andy Wilkinson
*/
@SpringBootTest(classes = AppConfiguration.class)
@Import(ActionPerformer.class)
class InheritedNestedTestConfigurationTests {
@MockBean
Action action;
@Autowired
ActionPerformer performer;
@Test
void mockWasInvokedOnce() {
this.performer.run();
verify(this.action, times(1)).perform();
}
@Test
void mockWasInvokedTwice() {
this.performer.run();
this.performer.run();
verify(this.action, times(2)).perform();
}
@Nested
class InnerTests {
@Test
void mockWasInvokedOnce() {
InheritedNestedTestConfigurationTests.this.performer.run();
verify(InheritedNestedTestConfigurationTests.this.action, times(1)).perform();
}
@Test
void mockWasInvokedTwice() {
InheritedNestedTestConfigurationTests.this.performer.run();
InheritedNestedTestConfigurationTests.this.performer.run();
verify(InheritedNestedTestConfigurationTests.this.action, times(2)).perform();
}
}
@Component
static class ActionPerformer {
private final Action action;
ActionPerformer(Action action) {
this.action = action;
}
void run() {
this.action.perform();
}
}
public interface Action {
void perform();
}
@SpringBootConfiguration
static class AppConfiguration {
}
}