JUnit Use Tutorials (iv)

Source: Internet
Author: User

First, the benefits of using spring test suites

When developing a spring-based application, if you also use JUnit directly for unit testing, you're missing out on the huge feast that spring offers us. Using JUnit for unit testing directly has the following four drawbacks:

1 causes multiple spring container initialization issues

Each execution of a test method creates an instance of a test case and invokes the Setup () method, depending on the calling process of the JUnit test method. As a general result, we initialize the spring container in the Setup () method, which means that if the test case has a number of test methods, the spring container will be repeatedly initialized multiple times. Although the speed of initializing a spring container is not too slow, the impact on test performance cannot be overlooked, because it is possible to perform time-consuming operations such as loading the hibernate mapping file when the spring container is initialized, and if the spring container must be duplicated each time a test method is executed;

With the spring test suite, the spring container initializes only once

2 need to use hard code to get the bean manually

In the test case class we need to get the target bean from the SPIRNG container to test from the Ctx.getbean () method, and also to perform a modeling operation that casts the type conversion. This tedious operation is in the code of the test case, which makes people feel cumbersome;

With the spring test suite, properties in the test case class are automatically populated with the corresponding bean for the spring container without having to set up the bean manually.

3 The database site is vulnerable to damage

The test method changes to the database are persisted to the database. Although the operation is for the development database, if the impact of the data operation is persistent, it may affect the subsequent test behavior. For example, users insert a user record with ID 1 in the test method, the first run will not be a problem, and the second run will cause the test case to fail because of the primary key conflict. Therefore, it should be able to complete the functional logic check, but also to restore the site after the test is completed, will not leave "Sequela";

With the spring test suite, Spring automatically rolls back the operation of the database after you validate it, ensuring that the database is not compromised, so repeated testing does not cause problems.

4) Inconvenient to check the correctness of the data operation

If we insert a successful login log into the login log, we do not check whether a record is actually added to the T_login_log table. In general, we may be opening the database, the naked eye to see whether the corresponding record, but this is a serious violation of the principle of automated testing. Imagine how to test with the naked eye when testing programs that include thousands of data manipulation behaviors.

As long as you inherit the use-case class of the spring test suite, you can access the database in the same transaction through JdbcTemplate (or DAO, etc.), and verify the correctness of the operation by querying the data changes.

Spring provides a suite of test suites that extend to junit test cases, and this suite of test suites solves all four of these problems, allowing us to test the application of spring more easily. This test suite is mainly composed of several classes under the Org.springframework.test package, which is simple, quick and easy to use.

Ii. Methods of Use

1) Basic usage

Package com.test;

Import Javax.annotation.Resource;

Import Org.junit.Test;
Import Org.junit.runner.RunWith;
Import org.springframework.test.context.ContextConfiguration;
Import Org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith (Springjunit4classrunner.class)
@ContextConfiguration (locations = {"classpath:config/ Applicationcontext-*.xml "," Classpath:services/ext/service-*.xml "}) public
class Userservicetest {

	@ Resource
	private Iuserservice userservice;

	@Test public
	void TestAddOpinion1 () {
		userservice.downloadcount (1);
		SYSTEM.OUT.PRINTLN (1);
	}

	@Test public
	void TestAddOpinion2 () {
		userservice.downloadcount (2);
		SYSTEM.OUT.PRINTLN (2);
	}
}

@RunWith (Springjunit4classrunner.class) for configuring the Environment for testing in spring

@ContextConfiguration (locations = {"Classpath:config/applicationcontext-*.xml", "classpath:services/ext/service-* . xml "}" is used to specify where the configuration file is located

@Resource inject the spring container bean object, notice the difference with @autowired

2) Transaction Usage

Package com.test;

Import Javax.annotation.Resource;
Import Org.junit.Test;
Import Org.junit.runner.RunWith;
Import Org.springframework.test.annotation.Rollback;
Import org.springframework.test.context.ContextConfiguration;
Import Org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Import org.springframework.test.context.transaction.TransactionConfiguration;

Import org.springframework.transaction.annotation.Transactional; @RunWith (Springjunit4classrunner.class) @ContextConfiguration (locations = {"classpath:config/applicationcontext-* . xml "," Classpath:services/ext/service-*.xml "}) @Transactional @TransactionConfiguration (TransactionManager ="
TransactionManager ")//@TransactionConfiguration (TransactionManager =" TransactionManager ", Defaultrollback = True)

	public class Userservicetest {@Resource private iuserservice userservice;
		@Test//@Transactional public void TestAddOpinion1 () {userservice.downloadcount (1);
	SYSTEM.OUT.PRINTLN (1); } @Test @Rollback (false) public void TestAddOpinion2 () {userservice.downloadcount (2);
	SYSTEM.OUT.PRINTLN (2); }
}

@TransactionConfiguration (transactionmanager= "TransactionManager") reads the transaction configuration named TransactionManager in the spring configuration file. Defaultrollback The default settings for the transaction rollback. This annotation is optional and can be used with @transactional and @rollback to complete transaction management. Of course, you can also use @transactional and @transactionconfiguration to match.

@Transactional open a transaction. Can be placed on a class or method and used on a class for all methods.

@Rollback transaction rollback configuration. Can only be placed on a method.

3) Inherit abstracttransactionaljunit4springcontexttests

package com.test;

Import Javax.annotation.Resource;
Import Org.junit.Test;
Import org.springframework.test.context.ContextConfiguration;
Import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;

Import org.springframework.test.context.transaction.TransactionConfiguration; @ContextConfiguration (locations = {"Classpath:config/applicationcontext-*.xml", "classpath:services/ext/service-* . xml "}" @TransactionConfiguration (TransactionManager = "TransactionManager", Defaultrollback = false) public class

	Userservicetest extends Abstracttransactionaljunit4springcontexttests {@Resource private iuserservice userservice;
		@Test public void TestAddOpinion1 () {userservice.downloadcount (1);
	SYSTEM.OUT.PRINTLN (1);
		@Test public void TestAddOpinion2 () {userservice.downloadcount (2);
	SYSTEM.OUT.PRINTLN (2); }
}

Abstracttransactionaljunit4springcontexttests: This class solves the problem of prolonging the session lifecycle that is resolved by configuring Opensessioninview in Web.xml, so inherit this class. This class has been preconfigured with the class level for good support, so there is no need to reconfigure @transactional and @runwith

4) Inheritance

Package com.test;

Import org.springframework.test.context.ContextConfiguration;
Import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
Import org.springframework.test.context.transaction.TransactionConfiguration;

@ContextConfiguration (locations = {"Classpath:config/applicationcontext-*.xml", "classpath:services/ext/service-* . xml "}"
@TransactionConfiguration (TransactionManager = "TransactionManager") Public
class Basetestcase Extends Abstracttransactionaljunit4springcontexttests {

}
Package com.test;

Import Javax.annotation.Resource;

Import Org.junit.Test;
Import Org.springframework.test.annotation.Rollback;

public class Userservicetest extends Basetestcase {

	@Resource
	private iuserservice userservice;

	@Test public
	void TestAddOpinion1 () {
		userservice.downloadcount (1);
		SYSTEM.OUT.PRINTLN (1);
	}

	@Test
	@Rollback (false) public
	void TestAddOpinion2 () {
		userservice.downloadcount (2);
		SYSTEM.OUT.PRINTLN (2);
	}
}

5) Synthesis

@RunWith (springjunit4classrunner.class) @ContextConfiguration @TransactionConfiguration @Transactional public class Persondaotransactionunittest extends Abstracttransactionaljunit4springcontexttests {final Logger Logger =

	Loggerfactory.getlogger (Persondaotransactionunittest.class);
	protected static int SIZE = 2;
	protected static Integer ID = new Integer (1);
	protected static String first_name = "Joe";
	protected static String last_name = "Smith";

	protected static String Changed_last_name = "Jackson";

	@Autowired protected Persondao Persondao = null;
	 /** * Tests that the size and the A/a match what is expected before the transaction.
	*/@BeforeTransaction public void Beforetransaction () {Testperson (true, last_name);
	 }/** * Tests person table and changes the "a".

		*/@Test public void Testhibernatetemplate () throws SQLException {assertnotnull ("the person DAO is null.", Persondao); collection<person> lpersons = PERSONDAO.FINDPERsons ();
		Assertnotnull ("person list is null.", lpersons);

		Assertequals ("Number of persons should be" + size + ".", Size, lpersons.size ());

			for (person person:lpersons) {assertnotnull (' person is null. ', person); if (Id.equals (Person.getid ())) {assertequals ("person's name should be" + first_name + ".", First_Name, person.ge
				Tfirstname ());

				Assertequals ("person's last name should" + Last_Name + ".", Last_Name, Person.getlastname ());

				Person.setlastname (Changed_last_name);
			Persondao.save (person);
	 }}/** * Tests that the size and the A/a match what is expected after the transaction.
	*/@AfterTransaction public void Aftertransaction () {Testperson (false, last_name);
	 /** * Tests Person table. */protected void Testperson (Boolean beforetransaction, String matchlastname) {list<map<string, object>> l

		Personmaps = Simplejdbctemplate.queryforlist ("SELECT * from person"); Assertnotnull ("person list is null.")", lpersonmaps);

		Assertequals ("Number of persons should be" + size + ".", Size, lpersonmaps.size ());

		map<string, object> Hperson = lpersonmaps.get (0); Logger.debug (beforetransaction?  "Before": "after") + "transaction."

		"+ hperson.tostring ());
		Integer id = (integer) hperson.get ("id");
		String firstName = (string) hperson.get ("first_name");

		String lastName = (string) hperson.get ("last_name");
			if (Id.equals (ID)) {assertequals ("person's name should be" + first_name + ".", first_name, FirstName);
		Assertequals ("person's last name should" + Matchlastname + ".", Matchlastname, LastName); }
	}

}

@BeforeTransaction performed before a transaction

@AfterTransaction executed after a transaction

@NotTransactional do not open a transaction

Well, this article as JUnit added here, I hope you can share the experience OH.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.