Unit test practice summary

Source: Internet
Author: User
(Synchronized from http://www.blogjava.net/AndersLin/archive/2006/06/12/52298.html)
Using unit testing in the system development process brings many benefits, most obviously:
When you become convinced of the value of comprehensive unit testing, you'll find that it begins to influence how you write code, and the frameworks you choose to use.

The first thing to solve in application unit testing isFocus of Unit Testing.
The focus of testing is the test logic. Test code should be written as long as there is logic. The test means to verify all outputs of all tested methods, including:
1. Return Value of the test method
2. Execution Process of the test method
For example:

Public class domainservice {
Private Static thedao Dao = new thedao ();
Public returnobject findbycond (string ){
Return (returnobject) Dao. getbeanbycondition ("select * From returnobject where cond =" + paramter, returnobject. Class );
}
}

There are two test cases for testing the findbycond method:
A. Test the correctness of the parameter passed to thedao. getbeanbycondition. If the parameter is not "select * From returnobject where cond = ?" And returnobject. class return null.
B. Check whether the returned object is correct.

In particular, the second point is more common in commercial applications. Generally, some methods do not have explicit output, and usually perform the write table operation. This method is to test its execution process. Of course, these methods contain logic.
A simple solution is to use access log (although there are not many such tests, the case code written is also strange ).

Public class serviceexample {
Private databasedao1 dao1;
Private databasedao2 dao2;

Public void nooutputmethod (){
If (...)
Dao1.update (...);
If (...)
Dao2.delete ();
}
}


The related test code can be as follows:

Public class mockdatabasedao1 implements databasedao1 {
Private map;
Public void setmap (MAP map ){
This. Map = map;
}

Public void Update (ARGs ){
Map. Put ("mockdatabasedao1.update", argS );
}
}


Public class mockdatabasedao2 implements databasedao2 {
Private map;

Public void setmap (MAP map ){
This. Map = map;
}

Public void Delete (ARGs ){
Map. Put ("mockdatabasedao2.delete", argS );
}
}


Public class serviceexampletestcase {
Private map = new hashmap ();
Public void testnooutputmethod (){
Daotest test = new daotest ();
Databasedao1 dao1 = new mockdatabasedao1 ();
Dao1.setmap (MAP );
Dao2.setmap (MAP );
Databasedao2 dao2 = new mockdatabasedao2 ();
Test. setdao1 (dao1 );
Test. setdao2 (dao2 );
Test. nooutputmethod ();
Assertequals (new Boolean (true), new Boolean (Map. containskey ("mockdatabasedao1.update ")));
Assertequals (new Boolean (true), new Boolean (Map. containskey ("mockdatabasedao2.delete ")));
}
}
 

The example only tests the execution process. In practice, all parameters can be verified.
We can also consider using AOP to improve this test method. Then, we needn't to do the same work, each time. We repeat it only once.

After discussing the testing focus, you need to look at the actual difficulties.
Unclear responsibilities 
Class or class method has unclear responsibilities, in violation of the SRP principle. A class or method handles the logic that shouldn't have been processed, so that unit testing needs to focus too much on external association classes.
Static Method
The static method makes it difficult for the caller to directly face the actual service class and replace it with other methods.
Direct access to the object instance
The caller directly instantiates the service object to use the service provided by the service object. Like the static method, the caller directly faces the service
J2se and J2EE standard libraries or other Class Libraries
There are many interface calls in the standard library, making it difficult for callers to test e. g JNDI, javamail, JAXP
Data Preparation and difficulties
Writing Test cases requires external preparation of a large amount of data

The following solutions are available to address these difficulties:
Restructuring System.
For codes with unclear responsibilities, only restructuring can achieve unit testing.
Self-delegate Test Pattern
For the class test, the self-agent test mode is used, so that some methods of the tested class can be rewritten during the test to achieve the purpose of the test. It is implemented through extend class override methods. The same is true for inner class mock. However, this method is awkward.
Compile stubs and mock object 
1. the mock of the interface is relatively easy. stubs and mock object are compiled to assist in the test, which is a very important technology. mock object is divided into dynamic mock and static mock. dynamic mock can be implemented with easymock.
2. Mock of a specific class is also very simple. It is usually implemented by subclass inheritance. The cglib framework can be used to achieve a great test Purpose.
3. Mock of the static method. Static methods are difficult because they directly face service objects. However, it is not impossible to test. Actually, we can use the features of classpath.
The method is simple. The mock class is exactly the same as the package, class name, and method signature for the mock class, but the method implementation is mock. When running the test case, compress the mock class into a jar (this is not required). When configuring classpath, make sure that the location of the jar is before the current class. The Code is as follows: staticmock.rar
Use mature unit test framework
In addition to the most basic JUnit, opensource provides many valuable unit test frameworks and is proficient in using these tools to improve testing efficiency. This includes preparing a large amount of data and J2EE framework code.
Optional automated testing tools for existing code:
1. pojo: JUnit, jmock or easymock
2. Data Object: ddtunit. Prepare a large amount of data.
3. Dao: dbunit. Initialize the database. Generate database data in batches.
4. EJB: mockejb or mockrunner
5. servlet: cactus
6. Struts: strutsunittest
7. xml: xmlunit
8. J2EE: mockrunner
9. Gui: jfcunit, marathor
10. Other: jtestcase (use XML to define the test process)

Unit tests in a layered architecture
1 unit test on web layer
Mainly tests the Data structuring logic of the controller.
If view uses the template engine, you need to test whether the page control script is correct.

2 domain service unit test
Includes business rules and business processes.
There are four types of service participants:
1. domain object
2. Dao object
3. Other services.
4. Tool
Deliverables:
1. The returned values include pojo and structured data (such as XML)
2. parameter value passed to the process node.
Features:
In concept, the business logic and business process are relatively independent. The actual code, although some business logic is relatively independent. However, some business logic and processes are combined. Because the business logic has a clear return value, the business rule can be independent into a method, which has a display return value, so that unittest can focus on the test of the business rule. The business flow usually does not display the returned values. In many practices, the operation is performed as a table write action, which makes the test more troublesome.
At the same time, however, the actual situation is that the business rules and business processes are merged.

Testing should cover:
1. The returned values include pojo, or structured data such as XML can be solved using xmlunit.
2. Access to the process node and the parameter values passed to the process node. That is, you can use the above access point method to test the business process.

3. Dao unit test
The first problem is the timing of the DaO data access layer unit test. Another word does not require unit testing.
Test is not required in several cases.
1. If Dao is a simple crud, you don't need to test it. In the future, when we use the 1.5 model, these crud will only be available in the parent class.
2. If the HBM file is automatically generated, no test is required.
The following are the situations to be tested:
1. If HBM files are manually written, you must ensure the correctness of hBM. Let's talk about how to test it later.
2. if Dao contains some combined queries, This is a logic and should be tested. If Dao queries also contain a sorting mechanism, This sorting logic is based on business fields, this is also a test. (The reason is: these logics can be implemented in Java code, but the performance is too poor. But since the logic of Java code is to be tested, there is no reason not to test the logic in SQL ).

The second question is how to test:
0. Test Data Preparation
You can export the data prepared by BA. You can use Excel to edit and generate a batch of data.
However, each unittest should focus on one concern, so the data of each unittest should be kept at a relatively small level.
In addition, because the order in which dbunit imports data is based on the sheet order, note that all foreign key tables are in the front. Otherwise, the foreign key does not exist during data insertion.

1. database selection
A. You can directly use the development database used by the Group. Advantage: All schemas are ready for use. Disadvantage: currently, the data cleanliness of the database cannot be guaranteed, and the connection speed is too slow.
B. Use HSQLDB. Advantage: with its memory mode, it can be started with the test program, which is simple and small. The schema can be customized and each of them has no influence on each other. Disadvantage: PLSQL is not supported. HSQLDB is recommended in most cases because of unittest requirements and performance considerations. Mock is required for PLSQL.

2. Test HBM
The HSQLDB memory database is used. During setup, the schemaexport tool class of Hibernate is used to export HBM to the database schema. If there is a potential problem, the test program will not pass.

3. Test Dao
It's easy to call the DaO program. For Save, update, and delete operations. The original connection needs to be used for query verification. For combined queries and logical sorting, this is the general practice.

4. when dbunit is used to test non-read-only operations, databaseoperation is often used. clean_insert policy. when there are many associated tables, the efficiency will be poor. because each setup and teardown operation will re-delete and then insert all the data. in addition, we also have a database operation test strategy, that is, to use a real database to roll back the transaction after each operation.

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.