Decouples configuration file dependencies to run unit tests.

Source: Internet
Author: User
Many people are now using the IOC framework. The new company also uses unity to manage object dependencies. From Program Put it in the configuration file, which is indeed more flexible for our system.
We can easily switch functions of programs by replacing objects. I think many people do not pay much attention to the other advantage. That is, decoupling between objects makes it possible for automated unit tests.
Imagine testing our business logic Code . If the business logic Code uses a database or network. For example, to process an order. This example calculates the price based on the product purchased by the user and the user's level.
Generate an order and insert it into the database, and then send an email notification to the customer. If we want to test our calculation price code. If the modules are coupled, you have to prepare the database to test the code for calculating the price.
And email server. In this case, automated testing is impossible. You cannot guarantee that the data in the database is what you expect. You cannot guarantee that the email server is always running normally.
Therefore, if the dependencies between our objects are loosely coupled (through interfaces), we can replace the database access layer object and mail sending object with the mock object to simulate the database and mail server.
. In this way, we can maintain that the unit test of our test computing order can run in the desired way every time. I think this is an important benefit of IOC decoupling. It is even more practical than functional replacement.
I don't know who has realized the benefits of functional replacement. After decoupling the business-layer code from the data access-Layer Code, you can switch the database implementation. But a few of them will do this.
Therefore, it seems more practical to implement automated unit tests than to implement database switching.

The above discussion mainly demonstrates a very important benefit of decoupling, that is, convenience of unit testing. Here are two examples of using IOC to manage objects. Containers are used to manage dependencies. But the last unit test
More friendly. Because it does not depend on external configuration files. We can easily test in unit tests.

Code Public   Class Order
{
// Some Properties

Public   Double Price { Get ; Set ;}
Public   String Useremail { Get ; Set ;}
}
Public   Interface Iorderservice
{
Void Createorder (order );
}
Public   Interface Iemailsender
{
Void Send ( String Email, String Content );

}
Public   Class Emailsender: iemailsender
{
Public   Void Send ( String Email, String Content)
{
// Access Network
}
}
Public   Interface Iorderrepository
{
Void Saveorder (order );
}
Public   Class Orderrepository: iorderrepository
{
Public   Void Saveorder (order)
{
// Access DB
}
}
Public   Class Orderservicev1: iorderservice
{

Public   Void Createorder (order)
{
Iorderrepository orderrepository = Ioccontainer. Resolve < Iorderrepository > (); // Get orderrepository implementation
Iemailsender emailsender = Ioccontainer. Resolve < Iemailsender > ();

Order. Price= 11;//Price CalculationAlgorithm...

Orderrepository. saveorder (order );

Emailsender. Send (order. useremail,"Thanks!");

}

}
Public ClassOrderservicev2: iorderservice
{
//Separating dependent interfaces from Methods facilitates mock implementation during unit testing
Iorderrepository orderrepository;
Iemailsender emailsender;

// The default constructor obtains the implementation from the container.
Public Orderservicev2 ()
{
Orderrepository = Ioccontainer. Resolve < Iorderrepository > (); // Get orderrepository implementation
Emailsender = Ioccontainer. Resolve < Iemailsender > ();
}
// Provides interface implementation independent of configuration files
Public Orderservicev2 (iorderrepository orderrepository, iemailsender emailsender)
{
This . Orderrepository = Orderrepository;
This . Emailsender = Emailsender;
}

Public   Void Createorder (order)
{
Orderrepository = Ioccontainer. Resolve < Iorderrepository > (); // Get orderrepository implementation
Emailsender = Ioccontainer. Resolve < Iemailsender > ();

Order. Price= 11;//Calculate the price algorithm...

Orderrepository. saveorder (order );

Emailsender. Send (order. useremail,"Thanks!");

}

}

Of course, you can also remove the default orderservicev2 constructor. Completely decouple our service from the configuration file and container. Then, when iorderservice is required
Container. And implements iorderrepository and iemailsender through constructor injection. Orderservicev1 is terrible. Decouples dependencies on specific object implementations, and lacks dependencies on configuration files.
To run a unit test, you must first configure the container configuration file. It also processes dependencies. For example, if a depends on B and B depends on C, you must configure B and C. Until no one depends on it.
In fact, you only need to process the direct dependency object of. There is no need to consider indirect dependency.

This small difference cannot be ignored. The first option is to rely too much on the configuration file, so that the person who writes the unit test will soon give up writing the automated unit test because of the trouble. Finally, the unit test project evolved into a debugging project.
.

Conclusion: Do not put any code for reading the configuration file into the implementation method. It should be placed in the constructor or attribute. The configuration file content can be easily replaced during unit tests.
Statements such as configurationmanager. etettings ["XXX"] cannot appear in the implementation method. It is best to use a Convention that is greater than the configuration when using containers. Reduce configuration file size and reduce configuration management tasks
For example, the implementation of iorderrepository is orderrepository and does not need to be configured. Just read the implementation according to the naming rule!

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.