What is spring TestContext?
Spring TestContext is a set of annotation-based test frameworks provided by spring, and spring TestContext has very good compatibility, seamless compatibility with unit test frameworks such as junit,testng, and more functionality on its base
It's a common practice to build applications with spring today, but when it comes to using traditional unit-testing techniques such as junit,testng and spring, there are a lot of things that don't work out 1. Spring Container initialization problem: This problem has been resolved in JUNIT4, and by using @beforeclass you can effectively prevent the spring container from being initialized multiple times 2. Hard-coded fetch bean: This problem is because JUnit is not compatible with spring, So when a unit test runs, it's not possible to explain Spring's unique annotations, so you need to use hard coding to get bean 3. Data onsite Destruction: a solution that can be used by JUnit for data onsite maintenance using Dbunit The details can be used to understand dbunit,spring TestContext through the author's dbunit use of AOP declarative transactions to roll back the unit test, effectively solve the problem of data field 4. Transactions: Usually our unit tests need to interact with the database, But the traditional JUnit components are testcase, and there is no concept of the transaction, and most of the time we need to look at the execution or overall performance of the transaction, especially for the long transaction module, Spring TestContext allow the control of unit test support transactions
Fortunately, Spring provides powerful support for unit testing, including: support for mainstream test frameworks Junit and TestNG support for using dependency injection in test classes denpendency injection support for automated transaction management of test classes using various annotation labels, Improve development efficiency and code simplicity Spring 3.1 supports the use of non-XML configuration methods and profile-based bean configuration patterns in test classes Spring TestContext Test Framework Architecture Spring Te Stcontext Test Framework Core class
The core of the TestContext test framework consists of three classes in the Org.springframework.test.context package, namely, the TestContext and Testcontextmanager classes and Testexecutionlistener interface. TestContext: It encapsulates the context in which the test case is run, regardless of the test framework currently in use. Testcontextmanager: It is the main entry point into the Spring TestContext Framework, which manages a TestContext instance and registers with all registered Testcontextmanager at the appropriate execution point The Testexecutionlistener listener in the release event notification: such as the preparation of test case instances, test methods before and after the implementation of the method call. Testexecutionlistener: This interface is responsible for responding to events published by Testcontextmanager.
Spring TestContext allows multiple listeners to be registered with the Testcontextmanager through @TestExecutionListeners annotations in a test case class
@TestExecutionListeners ({ dependencyinjectiontestexecutionlis Tener. Class, Dirtiescontexttestexecutionlistener. class }) public class xxxservicetest{ ...} |
Spring provides several Testexecutionlistener interface implementation classes, which are described below, respectively: Dependencyinjectiontestexecutionlistener: This listener provides automatic injection capabilities, It is responsible for parsing @Autowried annotations in test cases and completing automatic injection; Dirtiescontexttestexecutionlistener: Typically the test method does not cause damage to the Spring container context (changing the Bean's configuration information, and so on). If a test method does break the spring container context, you can explicitly add a @DirtiesContext annotation to the test method so that spring TestContext refreshes the context of the spring container after testing the method, and The work of Dirtiescontexttestexecutionlistener listeners is to parse @DirtiesContext annotations; Transactionaltestexecutionlistener: It is responsible for parsing @ Annotations to Transaction, @NotTransactional, and @Rollback and other transaction annotations. @Transaction annotations Let the test method work in a transactional environment, but the transaction is rolled back before the test method returns. You can use @Rollback (false) to submit a transaction before the test method returns. @NotTransactional annotations Let the test method not work in a transactional environment. In addition, you can change the transaction management strategy using @TransactionConfiguration annotations at the class or method level.
In JUnit 4, you can specify the runtime of a test case by @RunWith annotations, and the Spring TestContext Framework provides an extension to Org.junit.internal.runners.JUnit4ClassRunner The Springjunit4classrunner runtime, which is responsible for assembling the Spring TestContext test framework and unifying it into the JUnit 4 framework. Abstract test case class provided by TestContext
Spring TestContext provides two abstract test case classes for the JUnit 4.4 test framework, namely abstractjunit4springcontexttests and Abstracttransactionaljunit4springcontexttests, while the latter extends to the former. Let's take a look at the code for these two abstract test case classes:
@RunWith (Springjunit4classrunner.class) //Specify test Case Runtime
//Registered two Testexecutionlistener listeners
@ Testexecutionlisteners ({dependencyinjectiontestexecutionlistener.class, Dirtiescontexttestexecutionlistener.class}) public
abstract class Abstractjunit4springcontexttests implements Applicationcontextaware {
/**
* Logger available to subclasses.
* *
protected final Log logger = Logfactory.getlog (GetClass ());
/**
* The {@link ApplicationContext} that is injected into this test instance
* via {@link #setApplicationContex T (ApplicationContext)}.
* *
protected applicationcontext applicationcontext;
/**
* Set the {@link ApplicationContext} to is used by this test instance,
* provided via {@link Applicationcont Extaware} semantics.
* * Public
final void Setapplicationcontext (final applicationcontext applicationcontext) {
This.applicationcontext = ApplicationContext;
}
The Runwith annotation designates Springjunit4classrunner as the test case runtime, which is responsible for seamlessly deceitful act the TestContext test framework into the JUnit test framework, which is the Spring TestContext The fundamental place where it can be run. @TestExecutionListeners Note Registers two Testexecutionlistener listeners into the test case class, which are responsible for processing @Autowired and @DirtiesContext annotations, respectively. Provides the ability to automatically inject and refresh the Spring container context for test cases.
Abstracttransactionaljunit4springcontexttests extends to abstractjunit4springcontexttests, providing support for transaction management
Registers the listener for test case Transaction @TestExecutionListeners (Transactionaltestexecutionlistener.class)///Enables all methods of a test case to work in a transactional environment @ Transactional @SuppressWarnings ("deprecation") public abstract class Abstracttransactionaljunit4springcontexttests Extends Abstractjunit4springcontexttests {/** * the {@code simplejdbctemplate} that this base class manages, Ava
Ilable to subclasses.
* @deprecated as of Spring 3.2, use {@link #jdbcTemplate} instead.
* * @Deprecated protected simplejdbctemplate simplejdbctemplate;
/** * The {@code JdbcTemplate} that this is base class manages, available to subclasses.
* @since 3.2 * * * protected jdbctemplate jdbctemplate;
Private String sqlscriptencoding;
/** * Set the {@code DataSource}, typically provided via Dependency injection. * <p>this method also instantiates the {@link #simpleJdbcTemplate} and * {@link #jdbcTemplate} instance variabl
Es. */@Autowired public void Setdatasource (DataSourceDataSource) {this.simplejdbctemplate = new simplejdbctemplate (DataSource);
This.jdbctemplate = new JdbcTemplate (DataSource);
}/** * Specify the encoding for SQL scripts, if different from the platform encoding. * @see #executeSqlScript/public void setsqlscriptencoding (String sqlscriptencoding) {This.sqlscripten
coding = sqlscriptencoding;
/** * Count The rows in the given table. * @param tablename Table name to count rows in * @return The number of rows in the table */protected int Co
Untrowsintable (String tablename) {return jdbctestutils.countrowsintable (this.jdbctemplate, TableName);
/** * Count The rows in the given table, using the provided {@code WHERE} clause.
* <p>see the Javadoc for {@link jdbctestutils#countrowsintablewhere} for details. * @param tablename The name of the table to count rows in * @param whereclause the {@code WHERE} clause to aPpend to the query * @return the number of rows on the table that match the provided * {@code WHERE} clause * @since 3.2 */protected int Countrowsintablewhere (string tablename, String whereclause) {return JDBCT
Estutils.countrowsintablewhere (This.jdbctemplate, TableName, whereclause); }/** * Convenience method to deleting all rows from the specified tables.
Use * with caution outside of a transaction! * @param names the names of the tables from which to deletes * @return The total number of rows deleted from all Speci fied tables */protected int deletefromtables (String ... names) {return jdbctestutils.deletefromtables (th
Is.jdbctemplate, names); /** * Convenience to dropping all of the specified tables.
Use * with caution outside of a transaction!
* @param names the names of the tables to drop * @since 3.2/protected void Droptables (String ... names) { JDbctestutils.droptables (this.jdbctemplate, names); }/** * Execute the given SQL script.
Use with caution outside of a transaction! * <p>the script would normally be loaded by classpath. There should is one * statement per line. Any semicolons would be removed. <b>do not with this * method to execute DDL if you expect rollback.</b> * @param sqlresourcepath the
Spring resource path for the SQL script * @param continueonerror Whether or not to continue without throwing * Exception in the event of an error * @throws DataAccessException If there be an error executing a statement * And ContinueOnError was {@code false} */protected void Executesqlscript (String Sqlresourcepath, Boolean continue
OnError) throws DataAccessException {Resource Resource = This.applicationContext.getResource (Sqlresourcepath); Jdbctestutils.executesqlscript (This.jdbctemplate, New Encodedresource (Resource, this.sqlscriptencoding), ContinueOnError); }
}
Introducing dependencies on JUnit and spring-test libraries
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junitVersion}</version>
</dependency>
<dependency>
< groupid>org.springframework</groupid>
<artifactId>spring-test</artifactId>
< version>${org.springframework-version}</version>
<scope>test</scope>
</ Dependency>
Spring's TestContext test framework can be integrated into the JUnit 4.4 test framework and integrated into JUnit 3.8 and TestNG testing frameworks. Support for JUnit 3.8 and TestNG is currently available, and you can separate them in org.springframework.test.context.junit38 and Find the consolidated help class under the Org.springframework.test.context.testng package.