////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.
////

By implementing Grails Testing Support traits, unit tests inherit functionality that make writing tests concise and simple.

The following functionality is available to all tests

=== Modifying the Application Context

Any modifications to the context will be specific to that test class. A new context is created for each test class. Artifacts under test are subjected to dependency injection just like they are in the running application. The unit testing environment does not spin up the entire Spring application context with all of the beans that would normally be configured in the running application. Unit tests may register any beans necessary to carry out the test in a number of different ways.

==== doWithSpring

To provide or replace beans in the context, you can override the `doWithSpring` method in your test.

[source,groovy]
----
Closure doWithSpring() {{ ->
    someService(SomeService)
}}
----

NOTE: The syntax available in this closure is the same syntax that may be used in `grails-app/conf/spring/resources.groovy` for defining bean definitions.

==== resources.groovy

If you want your application's resources file to be loaded into the context, override the `loadExternalBeans` method.

[source,groovy]
----
boolean loadExternalBeans() {
    true
}
----

==== Spring configuration from plugins

If you would like the `doWithSpring` configuration of any loaded plugins to be invoked for your tests, override the `getIncludePlugins` method and return a list of strings representing the plugin names.

[source,groovy]
----
Set<String> getIncludePlugins() {
    ["springSecurityCore"].toSet()
}
----

WARNING: If you override this method, the default plugins will not be included. The default plugins are `core` and `eventBus`. If you want to add a plugin in addition to the defaults, add the defaults to your list.

==== Other Spring configuration

At any time during your tests, you can also directly call the `defineBeans` method. The `defineBeans` method can either take a closure, or an instance of a plugin.

[source,groovy]
----
include::{functionalSourceDir}/demo33/src/test/groovy/demo/DefineBeansSpec.groovy[tags=test_declaration,indent=0]
----

If you pass a plugin instance to the method, the `doWithSpring` will be executed.

[source,groovy]
----
void testSomething() {
    given:
    defineBeans(new MyCustomPlugin())

    expect:
    applicationContext.containsBean('someBeanAddedByDoWithSpring')
}
----

==== Autowiring The Test

It is possible to set up the test class itself for autowiring. Simply implement the link:{api}grails/testing/spring/AutowiredTest.html[`AutowiredTest`] trait, and beans will be injected into the test class.

For Example:

[source,groovy]
----
include::{functionalSourceDir}/demo33/src/test/groovy/demo/AutowiredTestSpec.groovy[tags=test_declaration,indent=0]
----

=== Manipulating Configuration

To change configuration for the context of your test class, override the `doWithConfig` method.

[source,groovy]
----
Closure doWithConfig() {{ config ->
    config['foo.bar'] = "x"
}}
----

NOTE: A test only needs to implement the link:{api}org/grails/testing/GrailsUnitTest.html[`GrailsUnitTest`] trait to get the above functionality. All of the other testing traits extend `GrailsUnitTest`, so implementing it directly is uncommon.
