Efficient unit test using DBUnit

xiaoxiao2021-03-06  72

DBUnit

There is usually some external dependencies, these objects, or other objects there are many associations. If we write units and component level testing for such objects, you can imagine a very troublesome thing. Because this external dependent existence makes it difficult to test the object. The white box test method, which is often mentioned, is basically the purpose of the isolation object by controlling the external dependency of the object, so that the status and related behavior of these objects can be operated.

Using analog objects (Mock Objects) or Stubs is a solution for external dependence of objects. By isolating the associated database access classes, the external dependency of the JDBC will be effective for the external dependency of the control target. However, the solution of the simulation object is not your heart to some special application system architecture, like the application system architecture that uses EJB's CMP (Container-Managed Persistence) or JDO (Java Data Objects), in these architecture, database Access objects are at the bottom of the bottom and very hidden.

The DBUnit architecture system for open source code written by Manuel Laflamme provides a very good solution for database dependencies within the control system. He allows programmers to manage the status of the database throughout the test process, which is important. With dbunit, before testing, we can implant our data sets we need, and after the test is completed, the database is fully retrosted to the state before the test.

In many successful software projects, test automation is often a key level. DBUNIT allows developers to create test sample code, which we can control the status of the database in these test cases. Moreover, these test cases are easy to automate. This is not necessary to worry about it in terms of artificial intervention during the test.

basic introduction

Configuring the first step in dbunit We first need to know how to generate a database schema, this file is an XML format, including the table of the database and related data information.

For example, there is a database table EMPLOYEE, we can express him in the form of SQL.

Moreover, we can see that a simple data set can be said

In DBUNIT, this table and sampling data information can be represented in the form of an XML file:

This generated XML format file can be used as the system. A sample template of all seed files. Creating multiple seed files for interrelated test scenarios is a very effective policy, just partitioning of different database files is a truth. A variety of subfile strategies can lock our test targets to a smaller range, and the target data can only target the table of the database, not the entire database. In order to implant different staff records to the target database, the XML data file we need is as follows: Now let DBUnit work together with the database schema we need, for programmers, we have two options for testing: Testing or combined with ANT by direct coding.

Encoding

The DBUnit framework provides a basic abstract test case class called DatabaseTestCase, which is a subclass of the basic Testcase in the JUnit framework. If we use this class, you must first implement two hook methods: getConnection () and getDataSet ().

Method getConnection () needs to return an IDTABASECONNECTION type object, which is a packaging class based on a normal JDBC connection. For example, the following code segment demonstrates the creation method of the IdatabaseConnection type connection object in the MySQL database environment.

Protected IdatabaseConnection getConnection () throws exception {class driverclass = class.Forname ("org.gjt.mm.mysql.driver");

Connection JDBCCONNECTION = DriverManager.getConnection ("JDBC: mysql: //127.0.0.1/hr", "hr", "hr");

Return New DatabaseConnection (JDBCCONNECTION);} method getDataSet () returns an IDataset type object, in fact, white, he is another expression of the seed files of our previous XML data.

Protected iDataSet getDataSet () throws exception {return new flatxmldataset ("HR-Seed.xml");} After these two basic methods, DBUnit can work in advance in advance by default. The DatabaseTestSTCase class provides two fixtures (I call it firmware, I don't know whether it is good?) Method to control the status before testing and testing. These two methods are: getSetupOperation () and getteardownoperation ().

An efficient implementation is to let the GetSetupOperation () method perform Refresh operations, through which we can use data in the seed file to update the data in the target database. Next, getteardownOperation (), let him perform a NONE action, which is not to be executed.

Protected DatabaseOperation GetSetupoperation () THROWS Exception {Return DatabaseOperation.Refresh;}

Protected DatabaseOperation GetteardownOperation () THROWS Exception {Return DatabaseOperation.none;}

There is also an effective way to perform Clean_Insert operation in the GetSetupOperation () method, which first deletes the data identified in the target database with the seed files we provide, and then insert us into the database. This implementation order guarantees our precise control of the database.

Code sample

In a J2EE-based human resource system, we hope to implement test automation on a data operation cycle, including new, retrieval, update, and deletion of staff. The remote interface defines the following business methods (for simple clear, omitting the Throws clause in the method).

// Translator Note: The EmployeeValueObject type object here, the translator is considered to be an object representing the staff entity information.

Public Void CreateEmployee (EmployeeValueObject Emplvo)

Public EmployeevalueObject GetEMPloyeeBysocialsecnum (String SSN) Public Void UpdateEmployee (EmployeeValueObject Emplvo)

Public void deleteemPloyee (EmployeeValueObject Emplvo)

Test the getEmployeeBysocialsecnum () method Requires a data to the target database, in addition, when testing the deleteemployee () method, and the UpdateEmployee () method is also performed on the basis of previously implanted records. Finally, the test class will first create a record using the CreateEmployee () method, and we need to verify that it will occur when the method is executed.

Below this DBUnit seed file called "Employee_hr_seed.xml", this file will be used below.

Test class EmployeessionFacadeTest, you need to extend DBUnit's basic class DatabaseTestSTSESESTSE and must provide the implementation of the getConnection () and getDataSet () method, and will be the same as the Database instance that is initialized with the EJB container in the getConnection () method, and getDataSet () method is responsible for reading Take the data of the EMPLOYEE_HR_SEED.XML file mentioned above.

The test method is quite simple, because DBUnit has handled the complex database lifecycle task. In order to test the getEmployeeBySocialsecnum () method, you only need to deliver a social security code number existing in the seed file, such as "333-29-9999".

// Translator Note: EmployeeFacade type object, the translator thinks that the mapping body representing the underlying database data public void testfindBysn () throws exception {

Employeefacade facade = // Obtain Somehow

EmployeevalueObject vo = facade.getemployeebysocialsecnum ("333-29-9999);

Testcase.assertNotnull ("Vo Shouldn't Be Null", Vo); Testcase.Assertequals ("Should Be Drew", "Drew", Vo.getFirstName (); testcase.assertequals ("Should Be Smith", "Smith" , vol.getname ());

In order to ensure that the creation staff in the operation cycle is no problem, we only need to make this method simple, then check if there is any abnormality, and the next step is that we have to do is in this new On the record, lookup operations, see if you can find the record you just created.

public void testEmployeeCreate () throws Exception {EmployeeValueObject empVo = new EmployeeValueObject (); empVo.setFirstName ( "Noah"); empVo.setLastName ( "Awan"); empVo.setSSN ( "564-55-5555");

Employeefacade Empfacade = // Obtain from Somewhere Empfacade.createEmployee (Empvo);

// perform a find by SSN TO ENSURE EXISTENCE

}

The updateemployee () method includes four steps, first find that the record we need to be updated, then update it, followed, re-find this record, confirm that the update operation is valid.

Public void testupdateemployee () throws exception {EmployeeFacade facade = // Obtain facade

EmployeevalueObject vo = facade.getemployeebysocialsecnum ("111-67-2222");

Testcase.assertNotnull ("Vo Was Null", VO); Testcase.Assrtequals ("First Name Should Be Jose", "Jose", Vo.getFirstName ());

Vo.setfirstname ("Ramon");

Facade.UpdateEmployee (VO);

EmployeeValueObject newvo = facade.getemployeebysocialsecnum ("111-67-2222"); testcase.assertnotnull ("Vo Was Null", newvo;

TestCase.Assertequals ("Name Should Be Ramon", "Ramon", newvo.getfirstname ());} Make sure that the deletion operation deleteemPloyee () method in the data operation cycle is basically similar. It is divided into three steps: first look for an existing record entity, then remove, and finally look up the same record, confirm that this record is not found. Public void testdeleteemployee () throws exception {EmployeeFacade facade = // Obtain facade

EmployeeValueObject VO = Facade.GetemployeeBysocialSecnum ("222-90-1111");

Testcase.assertNotnull ("Vo Was Null", VO);

Facade.deleteemPloyee (VO);

Try {EmployeeValueObject newvo = facade.getemployeebysocialsecnum ("222-90-1111");

Testcase.Fail ("Returned Removed Employee);

} catch (exception e) {// ignore}}

These test code is simple and easy to understand. Because these code is the test, it has been completely independent from the system program code, which makes testing simple. Also, the automation of these test cases is also easy to implement.

Combination with Ant

Compared to the basic class DatabaseTestCaseTcase, the DBUnit framework comes with the Ant function in the DBUnit framework, allow us to control the status of the database in the build.xml file of the Ant. This feature is quite powerful, because for many test cases, it Provide a quite concise solution. such as. Run the JUnit test in Ant, just as simple as defined below.

During the DBUnit task, in order to control the status of the database before and after the JUnit task, we need to create a "setup" action, in which the data content in the seed file is inserted in the database.

ClassName = "Org.dbunit.ant.dbunittask" />

URL = "JDBC: mysql: //127.0.0.1/hr"

Userid = "hr"

PASSWORD = "hr">

Then, a "Tear Down" action is also required. In this operation, the "setup" operation inserted recorded from the target database.

Packaging the JUnit task with the code above, which can load data to the target database before batch test, and after the test is completed, the loaded data is deleted.

ClassName = "Org.dbunit.ant.dbunittask" />

in conclusion

The status of the database can be managed during the test cycle, this functionality of the DBUnit framework makes the cycle of the creation and application of the test sample code. Moreover, by controlling the main dependent object of the database, it is easier to automate the test using the DBUnit framework. DBUNIT exquisite design makes learning to use it very simple. In your test plan, if you can use it correctly, then it will be a large increase in code stability, of course, it will also make your development team confidence.

转载请注明原文地址:https://www.9cbs.com/read-119978.html

New Post(0)