Major Case reconstruction and serialization 15: Use mock technology to complete testing

Source: Internet
Author: User
Tags date now

In the fifth reconstruction, we introduced the database design. User information should be read from the database, and the greeting database should be stored in the database, and support adding and updating. The introduction of databases makes automated testing difficult, because the data status is always changing and the test process cannot be reproduced. This is what we don't want to see. Therefore, we separated the business and database access during the design, forming the userdao and greetingruledao. In this case, our design should follow the "Dependency inversion" principle. We will design userdao and greetingruledao as interfaces and write their implementation userdaoimpl and greetingruledaoimpl. This design creates a condition for the Implementation class of mock to drop userdao and greetingruledao.

This is our design:

Figure 4.3 helloworld design diagram

 

To this end, we have compiled such a test program:

1 private helloworld = NULL; 2 Private greetingtouserimpl greetingtouser = NULL; 3 private vertex greetingabouttime = NULL; 4 private final static list <greetingrule> greeting_rules = getrules (); 5 6/** 7 * @ throws Java. lang. exception 8 */9 @ before10 public void setup () throws exception {11 helloworld = new helloworld (); 12 greetingtouser = new greetingtouserimpl (); 13 gree Tingabouttime = new greetingabouttimeimpl (); 14 helloworld. setgreetingtouser (greetingtouser); 15 helloworld. setgreetingabouttime (greetingabouttime); 16} 17 18/** 19 * @ throws Java. lang. exception20 */21 @ after22 public void teardown () throws exception {23 helloworld = NULL; 24 greetingtouser = NULL; 25 greetingabouttime = NULL; 26} 27 28/** 29 * Test Method for {@ link org... helloworld # sayhello (Java. util. Date, Java. lang. string )}. 30 */31 @ test32 public void testsayhellointhemorning () {33 final date now = dateutil. createdate (2013, 9, 7, 9, 23, 11); 34 final long userid = 2013090701; 35 36 userdao = createmock (userdao. class); 37 greetingruledao = createmock (greetingruledao. class); 38 CT (userdao. loaduser (userid )). andanswer (New ianswer <user> () {39 @ override40 public user answer () Throws throwable {41 user = new user (); 42 user. setuserid (userid); 43 user. setname ("Bao Xiaomei"); 44 return user; 45 }}); 46 CT (greetingruledao. findallgreetingrules () 47. andanswer (New ianswer <list <greetingrule> () {48 @ override49 public list <greetingrule> answer () throws throwable {50 return greeting_rules; 51 }}); 52 replay (userdao); 53 replay (greetingruledao); 54 55 greetingtouser. setuserdao (userdao ); 56 greetingabouttime. setgreetingruledao (greetingruledao); 57 58 string result = helloworld. sayhello (now, userid); 59 assert. assertequals ("Hi, Bao Xiaomei. Good morning! ", Result); 60 verify (userdao); 61 verify (greetingruledao); 62}

 

This test procedure is long, but the rest is soy sauce. The core is the testsayhellointhemorning () use case, that is, greeting the Good morning test case. Userdao and greetingruledao are two interfaces. when instantiating them, We didn't create their implementation classes, but created them using mock:

1     UserDao userDao = createMock(UserDao.class);2     GreetingRuleDao greetingRuleDao = createMock(GreetingRuleDao.class);

 

Then we began to define their behavior loaduser () and getallgreetingrules (). In this test case, we do not care about how they query data in the database and return data. We only care about whether they get the expected parameters and require them to return a result as required:

1 Final long userid = 2013090701; 2 round CT (userdao. loaduser (userid )). andanswer (New ianswer <user> () {3 @ override4 public user answer () throws throwable {5 user = new user (); 6 user. setuserid (userid); 7 user. setname ("Bao Xiaomei"); 8 return user; 9 }});

 

We want the tested program to call userdao. loaduser (userid) during execution, and the input parameter userid = 2013090701. If the parameter passed in during the test is this value, this checkpoint can pass, otherwise it cannot pass. Then we want this function to return the user object "Bao Xiaomei. Through the mock program, we completely strip the database access process out of automated testing, instead of verifying its input parameters and specifying the returned results required for the test. That is to say, the data access process is mock, which greatly reduces the test difficulty.

If the mock program of userdao and greetingruledao cannot obtain the specified parameter, the test fails. That is to say, the parameter passed to the Mock program is also an output to be verified by the test program. Then, the mock program returns the specified value, which is an input of the tested program. Finally, the tested program returns the result based on this input, which is verified by the test program and the test ends (4.4 ).

 

Figure 4.4 automated testing of helloworld

The bus layer in the figure is part of our code and should be tested automatically. In this case, testing is used to verify the input and output. The request sent by the web layer to the bus layer, that is, calling a method of a class in the bus layer is an input in the test case. The returned value after the method is executed is an output of the test case. However, the input and output are not all of the test cases. After processing at the bus layer, after a series of logical judgment and data operations, the DaO layer will be called for data access. The parameter passed when the DaO layer is called is another output of the test case. In the figure, from the input at the DaO layer to its output, the database access process is dropped by the mock program mock because it is not in the test scope of this case. Then the DaO layer returns a result to the bus layer, which is another input of the test case. Then, the bus layer processes the returned result again and returns the final result to the web layer. This is a complete process of automated testing using mock.

With automated testing, the testing program no longer verifies that the background database is correct, nor does it verify that the front-end web applications and front-end devices are correct. In this example, the real purpose of the system is to display greetings to users on the foreground, so there will be an action or servlet calling helloworld:

1     Date now = DateUtil.getNow();2     String user = SessionUtil.getCurrentUser(session);3     HelloWorld helloWorld = new HelloWorld();4     String greeting = helloWorld.sayHello(now, user);5     request.setAttribute(“greeting”, greeting);

 

However, none of these procedures are suitable for automated testing and should be manually tested. Looking back at the creation process of helloworld automated testing, we can easily find that it achieves the separation of business logic from web applications and data access at the beginning of its design, so it can easily establish automated testing. However, unfortunately, most of our legacy systems did not take this into account at the beginning of the design. Therefore, it is unrealistic to establish an automated testing mechanism at the beginning of reconstruction. We can only use manual testing and qtp. Automated testing can be carried out only when the system architecture meets the conditions for automated testing through restructuring.

There is no doubt that testing and restructuring form a strange circle of "chicken or eggs", which has become a major obstacle to restructuring our practical system. This book will discuss this topic in detail later (For details, refer to Chapter 1 test dilemma) to solve this mystery for you.

Big talk rebuilding serialization home: http://www.cnblogs.com/mooodo/p/talkAboutRefactoringHome.html

Note: I hope that the author or source should be noted to show my respect for the author when I reprint this article. Thank you!

Major Case reconstruction and serialization 15: Use mock technology to complete testing

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.