Switch @SpringBootTest to UseMainMethod.NEVER by default

See gh-22405
pull/32405/head
Phillip Webb 2 years ago
parent 48f3cd75d4
commit 7f5785182d

@ -153,25 +153,17 @@ For example, here is an application that changes the banner mode and sets additi
include::code:custom/MyApplication[] include::code:custom/MyApplication[]
Since customizations in the `main` method can affect the resulting `ApplicationContext`, Spring Boot will also attempt to use the `main` method for tests. Since customizations in the `main` method can affect the resulting `ApplicationContext`, it's possible that you might also want to use the `main` method to create the `ApplicationContext` used in your tests.
By default, `@SpringBootTest` will detect any `main` method on your `@SpringBootConfiguration` and run it in order to capture the `ApplicationContext`. By default, `@SpringBootTest` will not call your `main` method, and instead the class itself is used directly to create the `ApplicationContext`
If your `@SpringBootConfiguration` class doesn't have a main method, the class itself is used directly to create the `ApplicationContext`.
In some situations, you may find that you can't or don't want to run the `main` method in your tests. If you want to change this behavior, you can change the `useMainMethod` attribute of `@SpringBootTest` to `UseMainMethod.ALWAYS` or `UseMainMethod.WHEN_AVAILABLE`.
If that's the case, you can change the `useMainMethod` attribute of `@SpringBootTest` to `UseMainMethod.NEVER`. When set to `ALWAYS`, the test will fail if no `main` method can be found.
When set to `WHEN_AVAILABLE` the `main` method will be used if it is available, otherwise the standard loading mechanism will be used.
For example, you might have the following application class: For example, the following test will invoke the `main` method of `MyApplication` in order to create the `ApplicationContext`.
If the main method sets additional profiles then those will be active when the `ApplicationContext` starts.
include::code:never/MyApplication[] include::code:always/MyApplicationTests[]
If a test wants to use the `MyApplication` configuration without calling the main method, it can be written as follows:
include::code:never/MyApplicationTests[]
The test above will still use `MyApplication` to create the `ApplicationContext`, however, it won't call `MyCode.expensiveOperation()` since the `main` method is not invoked.
If you want to do the opposite, and ensure that the `main` method is always invoked, you can set the `useMainMethod` attribute of `@SpringBootTest` to `UseMainMethod.ALWAYS`.
If this property is set, and no `main` method can be found the test will fail.

@ -14,14 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.docs.features.testing.springbootapplications.usingmain.never; package org.springframework.boot.docs.features.testing.springbootapplications.usingmain.always;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod; import org.springframework.boot.test.context.SpringBootTest.UseMainMethod;
@SpringBootTest(useMainMethod = UseMainMethod.NEVER) @SpringBootTest(useMainMethod = UseMainMethod.ALWAYS)
public class MyApplicationTests { public class MyApplicationTests {
@Test @Test

@ -1,30 +0,0 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.usingmain.never;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
MyCode.expensiveOperation();
SpringApplication.run(MyApplication.class, args);
}
}

@ -1,27 +0,0 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.usingmain.never;
public final class MyCode {
private MyCode() {
}
static void expensiveOperation() {
}
}

@ -14,14 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.docs.features.testing.springbootapplications.usingmain.custom.never package org.springframework.boot.docs.features.testing.springbootapplications.usingmain.custom.always
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod import org.springframework.boot.test.context.SpringBootTest.UseMainMethod
import org.springframework.context.annotation.Import import org.springframework.context.annotation.Import
@SpringBootTest(useMainMethod = UseMainMethod.NEVER) @SpringBootTest(useMainMethod = UseMainMethod.ALWAYS)
class MyApplicationTests { class MyApplicationTests {
@Test @Test

@ -1,29 +0,0 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.usingmain.custom.never
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.docs.using.structuringyourcode.locatingthemainclass.MyApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
MyCode.expensiveOperation()
runApplication<MyApplication>(*args)
}

@ -1,24 +0,0 @@
/*
* Copyright 2012-2022 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.docs.features.testing.springbootapplications.usingmain.custom.never
class MyCode {
companion object {
fun expensiveOperation() {
}
}
}

@ -131,7 +131,7 @@ public @interface SpringBootTest {
* @return the type of main method usage * @return the type of main method usage
* @since 3.0.0 * @since 3.0.0
*/ */
UseMainMethod useMainMethod() default UseMainMethod.WHEN_AVAILABLE; UseMainMethod useMainMethod() default UseMainMethod.NEVER;
/** /**
* An enumeration web environment modes. * An enumeration web environment modes.

@ -55,7 +55,7 @@ class SpringBootTestAnnotation implements ContextCustomizer {
private SpringBootTestAnnotation(SpringBootTest annotation) { private SpringBootTestAnnotation(SpringBootTest annotation) {
this.args = (annotation != null) ? annotation.args() : NO_ARGS; this.args = (annotation != null) ? annotation.args() : NO_ARGS;
this.webEnvironment = (annotation != null) ? annotation.webEnvironment() : WebEnvironment.NONE; this.webEnvironment = (annotation != null) ? annotation.webEnvironment() : WebEnvironment.NONE;
this.useMainMethod = (annotation != null) ? annotation.useMainMethod() : UseMainMethod.WHEN_AVAILABLE; this.useMainMethod = (annotation != null) ? annotation.useMainMethod() : UseMainMethod.NEVER;
} }
@Override @Override

@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod;
import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.boot.test.system.OutputCaptureExtension;
@ -32,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb * @author Phillip Webb
*/ */
@ExtendWith(OutputCaptureExtension.class) @ExtendWith(OutputCaptureExtension.class)
@SpringBootTest(useMainMethod = UseMainMethod.NEVER) @SpringBootTest
class SampleLdapApplicationTests { class SampleLdapApplicationTests {
@Test @Test

@ -21,7 +21,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
@ -34,8 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Madhura Bhave * @author Madhura Bhave
*/ */
@SpringBootTest(useMainMethod = UseMainMethod.NEVER, webEnvironment = WebEnvironment.NONE, @SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { "enableEnvironmentPostProcessor=true" }) // gh-28530
properties = { "enableEnvironmentPostProcessor=true" }) // gh-28530
@ActiveProfiles("hello") @ActiveProfiles("hello")
class ActiveProfilesTests { class ActiveProfilesTests {

@ -20,12 +20,11 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.UseMainMethod;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
// gh-29169 // gh-29169
@SpringBootTest(useMainMethod = UseMainMethod.NEVER, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AttributeInjectionTests { class AttributeInjectionTests {
@Autowired(required = false) @Autowired(required = false)

Loading…
Cancel
Save