Test-driven development practices-refactoring

Source: Internet
Author: User
Previous Article Article TestDriverDevelopment practices-getting started we will talk about some basic test-driven development processes:

1. WriteUnit TestTurn him on the red light

2. write code to make the test a green light

3. refactor the code

Next we need to start refactoring. You may ask why and when to start restructuring.

To clarify the code structure and remove some repeated code, for example, to execute an SQL statement, we first write:

Code
1 private connstr = "Server =.; database = testdb; uid = SAS; Pwd = 123"
2 Public int add (string loginname)
3 {
4 int COUNT = 0;
5 using (sqlconnection conn = new sqlconnection (connstr ))
6 {
7 conn. open ();
8 sqlcommand cmd = new sqlcommand ("insert (loginname) value ('" + loginname + "')", Conn );
9 COUNT = cmd. executenonquery ();
10 cmd. Dispose ();
11 conn. Close ();
12}
13 return count;
14}
15
16 public int Delete (string loginname)
17 {
18 int COUNT = 0;
19 using (sqlconnection conn = new sqlconnection (connstr ))
20 {
21 conn. open ();
22 sqlcommand cmd = new sqlcommand ("delete from loginusers where loginname = '" + loginname + "'", Conn );
23 COUNT = cmd. executenonquery ();
24 cmd. Dispose ();
25 conn. Close ();
26}
27 return count;
28}

Besides SQL statements,OthersThey are all the same, so we can refactor them like this:

1 private int executesql (string SQL)
2 {
3 int COUNT = 0;
4 using (sqlconnection conn = new sqlconnection (connstr ))
5 {
6 conn. open ();
7 sqlcommand cmd = new sqlcommand (SQL, Conn );
8 count = cmd. executenonquery ();
9 cmd. Dispose ();
10 conn. Close ();
11}
12 Return count;
13}
14 public int add (string loginname)
15 {
16 return executesql ("insert (loginname) value ('" + loginname + "')");
17}
18 public int Delete (string loginname)
19 {
20 return executesql ("delete from loginusers where loginname = '" + loginname + "'");
21}

After the reconstruction, is the code much clearer?

So when will reconstruction begin? We feel that the code is too repetitive, the hierarchy is messy, and so on (that is, the legendary code with bad taste) can be reconstructed and tested, do you still need to be afraid of code correction or error?

Next we will rebuild the use cases in the previous article according to the design pattern principles (single responsibility principle, interface isolation principle, dependency inversion principle, etc)

Then let's look back at the login method, which contains the verification and data operation code. According to the single responsibility principle, we need to put them in different classes and the following code is available:

1 public interface iemployeeservice
2 {
3 bool login (string loginname, string password );
4 bool validateloginname (string loginname );
5}

In the above Code, we define a service-layer interface, and take the verification separately as a method.

The implementation of the service layer is as follows:

1 public class employeeservice: iemployeeservice
2 {
3 private iemployeedataaccess _ empdao;
4
5 Public employeeservice (iemployeedataaccess empdao)
6 {
7
8 _ empdao = empdao;
9}
10
11 Public bool validateloginname (string loginname)
12 {
13 return! String. isnullorempty (loginname );
14}
15
16/** // <summary>
17 // employee login
18 /// </Summary>
19 /// <Param name = "loginname"> logon name </param>
20 /// <Param name = "password"> password </param>
21 /// <returns> </returns>
22 public bool login (string loginname, string password)
23 {
24 if (validateloginname (loginname ))
25 {
26 if (_ empdao. getcount (loginname, password)> 0)
27 {
28 return true;
29}
30}
31
32 return false;

33}

We can see from the above service layer that we call the implementation of the data layer interface, rather than directly calling the operations on the data layer, so that the relationship between the service layer and the data layer is de-even, the service layer is not directly dependent on the data layer, but on the data layer interface. What are the advantages of this?

For example, our current data layer implementation interacts with sqlserver. Next time we want to interact with XML, what should we do, we only need to implement a data layer that interacts with XML data, and other code will not need to be modified.

In fact, the model is prepared for changes. If the project is to be delivered, nothing will happen. What else do we do? What do you think?

Here is a bit out of question. Next we will go back to the topic. The data interface is defined as follows:

1 public interface iemployeedataaccess
2 {
3 int getcount (string loginname, string password );
4}

Here is the data layer:

1 public class employeeaccess: iemployeedataaccess
2 {
3 iemployeedataaccess member # region iemployeedataaccess Member
4
5 Public int getcount (string loginname, string password)
6 {
7 throw new notimplementedexception ();
8}
9
10 # endregion
11}

Finally, we need to modify our test cases so that they can continue to pass. The final test case is as follows:

1 [testfixture]
2 public class employeeservicetest
3 {
4 private iemployeeservice empservice;
5
6 [testfixturesetup]
7 public void Init ()
8 {
9 var da = new mock <iemployeedataaccess> ();
10 da. setup (DD => DD. getcount (it. is <string> (S => S = "admin"), it. is <string> (S => S = "PWD "))). returns (1 );
11 empservice = new employeeservice (DA. Object );
12}
13
14 [test]
15 public void logintest ()
16 {
17 assert. istrue (empservice. login ("admin", "PWD"), "Logon Failed ");
18}
19
20 [test]
21 public void validatenullloginname ()
22 {
23 assert. istrue (! Empservice. validateloginname (null), "user is null verification test failed ");
24}
25
26 [test]
27 public void validateemptyloginname ()
28 {
29 assert. istrue (! Empservice. validateloginname (""), "verification test failed for empty ");
30}
31}

Here the Refactoring is here, here the service layer test using Moq mock framework can be down in the http://code.google.com/p/moq, so here the mock simulation data layer is tested, this framework is very good for hierarchical development and testing. When the data layer is not written, we can simulate the data layer to provide data and directly test the service layer.

 

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.