Dedependencies on Singleton classes

Source: Internet
Author: User

When speaking at the Internet Software Testing conference in Hangzhou last Saturday, the topic of testability was mentioned. Let's give an example: "Class B has a dependence on Class, class A is a singleton class. Class B uses a function in Class A that needs to be mock. How can this problem be solved?" Originally, this isCodeA typical model mentioned in art, which is described in detail in this book. But today I received an email from an audience asking me how to answer this question.

 

I haven't written a blog for a long time, so I wrote a simple code to illustrate this problem.

 

Problem:

The Singleton class is a single-piece class that implements a function named GetUserName (). The GetUserName function needs to connect to the database and retrieve the user name from the database. The dependsonsingleton class is the tested class. The sayhello function in this class uses the GetUserName function of the singleton class. When we perform a unit test on the dependsonsingleton class, we obviously do not want to set up a real database, therefore, the ideal situation is to use mock to obtain the GetUserName function of a singleton class that can be controlled. If the singleton class is not a single-piece class, this is very simple. Use the interface extraction method to extract the interface from the singleton class, and then you can use the mock technology. However, because Singleton is a single-piece class, this is tricky: Singleton. getinstance returns a singleton object determined by the getinstance logic, so that it cannot be directly inserted into a mock object.

 

Code:

Code 1 Public   Class Singleton {
2 Static   Private Singleton _ instance;
3 Public   Final String Username =   " Dennis " ;
4
5 Private Singleton (){
6 }
7
8 Static Singleton getinstance (){
9 If ( Null   = _ Instance ){
10 _ Instance =   New Singleton ();
11 }
12 Return _ Instance;
13 }
14
15 String GetUserName () Throws Exception {
16 // Connect to DB and return data from DB
17 // Throw exception instead
18 Throw   New Exception ( " There's no dB exist " );
19 }
20 }

 

1 Public   Class Dependsonsingleton {
2
3 ...
4 Public String sayhello () Throws Exception {
5 Return   " Hi, "   + Singleton. getinstance (). GetUserName ();
6 }
7 }

 

Solution:

In fact, the idea of solving this problem is mainly to solve the issue of "separation" according to the book "Art of code modification. In Singleton, The getinstance function is not controlled, so the simplest way is to add a settestinginstance function for the singleton class and use this function to inject a controlled instance.

 

Modified singleton:

Code 1 Public   Class Singleton {
2 Static   Private Singleton _ instance;
3 Public   Final String Username =   " Dennis " ;
4
5 Private Singleton (){
6 }
7
8 Public   Static Singleton getinstance (){
9 If ( Null   = _ Instance ){
10 _ Instance =   New Singleton ();
11 }
12 Return _ Instance;
13 }
14
15 Public   Static   Void Settestinginstance (Singleton instance ){
16 _ Instance = Instance;
17 }
18
19 Public String GetUserName () Throws Exception {
20 // Connect to DB and return data from DB
21 // Throw exception instead
22 Throw   New Exception ( " There's no dB exist " );
23 }
24 }

 

 

Test code:

Code 1 Import JUnit. Framework. Assert;
2 Import JUnit. Framework. testcase;
3
4 Import Org. easymock. easymock;
5
6 Public   Class Testdependsonsingleton Extends Testcase {
7 Public   Void Testsayhello () Throws Exception {
8 Singleton depend = Easymock. createmock (Singleton. Class );
9 Singleton. settestinginstance (depend );
10
11 Easymock. Exact CT (depend. GetUserName (). andreturn ( " Dennis " );
12 Easymock. Replay (depend );
13
14 Dependsonsingleton ITU =   New Dependsonsingleton ();
15 Assert. assertequals ( " Hi, Dennis " , ITU. sayhello ());
16 Easymock. Verify (depend );
17 }
18 }

 

 

 

 

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.