Tutorial Series-springboot Unit Test Way

Source: Internet
Author: User
Tags throw exception throwable

Directory

    • Goal
    • I. About UNIT Testing
    • Ii. about Junit
    • Three, springboot-unit test
      • Project Dependencies
      • Test examples
    • Four, mock test
    • V. Last
Goal
    1. Understanding the background of unit tests
    2. Learn how to implement interface testing with Springboot
    3. Learn how to use Mokito to do code mock-up
I. About UNIT Testing

Unit testing is actually a cheap technique that is created by developers to run test code that is used to test the correctness of program modules (the smallest unit of software design).
The so-called minimum unit, refers to the application of the smallest testable parts. In the object-oriented realm, the smallest cell corresponds to a member method of a class.

The usual meaning of unit tests is used to validate the behavior of a given scenario, a condition, for example:

I want to verify

    Equals 方法,在两个对象类型不一致时应该返回 false

Unit testing is intended to ensure the quality of the core code by ensuring that the basic unit baseline tests are independent and unrelated to each other.

Each piece of unit test code will certainly contain several parts :

    • Arrange
      Used to initialize some parameters or dependent objects that are required by the method being tested.

    • Act method
      Used to call the method being tested for testing.

    • Assert
      Used to verify that the test method is performing as expected or whether the result meets expectations

See! Not very complicated, but most developers don't like to do unit tests.
Moreover, there is a very interesting phenomenon, the higher the level of the programmer, the less like to write test code, why?

"Because unit tests are mostly used to prevent low-level programmers from digging holes."

This is not what I said, but it represents a considerable part of the programmer's voice.

Then, the unit test should not be done, is not the issue to be discussed in this article.
We recommend that you read the "-java version of Unit Testing" (Programmer's Trilogy series) side of the book, read it and then make their own understanding.

In order to test a bridge, it should not only be in clear weather, driving a car from the middle of the bridge, it is considered to have completed the test of the bridge

Ii. about Junit

Next, let's talk about the JUnit framework, which is the most popular Java unit testing framework.
The JUnit Creator is Kent Beck and Erich Gamma, and since its advent, the JUnit biosphere has been very large.
A large number of applications and development frameworks are based on Junit as a standard test component, which of course includes the Spring Series framework.

A typical JUnit unit test class:

class StandardTests {    @BeforeClass    static void initAll() {    }    @Before    void init() {    }    @Test    void justTest() {    ...    assertTrue(...)    }        @After    void tearDown() {    }    @AfterClass    static void tearDownAll() {    }}

Description

Key points Description
@BeforeClass Execute before the current class test
@Before Executed before each test method
@Test Declaring test methods
@After After each test method is executed
@AfterClass Executes after the current class test

The above note is relatively easy to understand, it is only @BeforeClass and @Before, the former is a static method,
Executes only once before the entire test case class starts, and the latter is triggered before the method test and may be executed more than once.

Currently the latest version is JUnit 5, interested to see the introduction of https://junit.org/junit5 official website

To get a clearer understanding of how JUnit works, here's a source snippet:

    public void runBare() throws Throwable {        Throwable exception = null;        setUp();        try {            runTest();        } catch (Throwable running) {            exception = running;        } finally {            try {                tearDown();            } catch (Throwable tearingDown) {                if (exception == null) exception = tearingDown;            }        }        if (exception != null) throw exception;    }

This is an earlier version of the TestCase class, one of the implementations, which is basically consistent with what we call the idea.
However, annotation-based implementations are provided by JUNIT4 and can be looked at in depth when interested.

Keywords
TestCase, Junit4testadapter, Blockjunit4classrunner

Three, springboot-unit test

Springboot provides the spring-boot-starter-test for implementing unit tests.

Project Dependencies
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${spring-boot.version}</version></dependency>
Test examples
@RunWith (Springrunner.class) @SpringBootTest (classes = demoboot.class) public class Restapitest {private Mockmvc MOCKMV    C    Private Objectmapper mapper = new Objectmapper ();    @Autowired private Webapplicationcontext context;    @Autowired private Restdatamanager DataManager;    private static final String CUSTOMER = "Lilei";    Private Pet Polly;    Private Pet Badboy; @Before public void Setupmockmvc () throws Exception {Mockmvc = Mockmvcbuilders.webappcontextsetup (context). Buil        D ();    InitData ();        } private void InitData () {//Clear original Pet information datamanager.clearpets (CUSTOMER);        Add new pet Information polly = new pet ();        Polly.settype ("Bird");        Polly.setname ("Polly");        Polly.setdescription ("The rapid Speaker");        Datamanager.addpet (CUSTOMER, Polly);        Badboy = new Pet ();        Badboy.settype ("Dog");        Badboy.setname ("Badboy");        Polly.setdescription ("the Monster"); Datamanager.addpet (CUSTOMER, badboy); } @Test public void Testget () throws Exception {Mockmvc.perform (Mockmvcrequestbuilders.get ("/rest/pets/{cust Omer}/{petid} ", CUSTOMER, Polly.getpetid ()). Andexpect (Mockmvcresultmatchers.status (). isOk ()). Andexpect (Mockmvcresultmatchers.content (). ContentType (MEDIATYPE.APPLICATION_JSO N_utf8). Andexpect (Mockmvcresultmatchers.content (). JSON (Mapper.writevalueasstring (p    Olly)). Anddo (Mockmvcresulthandlers.print ()); }}

Description

Springrunner inherits from Springjunit4classrunner, which is the spring framework base class based on the JUnit implementation.
If you remember the Blockjunit4classrunnermentioned earlier, it should be easy to guess that Spring's implementation class integrates the class.

So, what did Springrunner do? Nothing, just a correction of the name (on the importance of naming)

The role of @SpringBootTest

The code comments are as follows:

Points

    1. The default is to use the Springbootcontextloader class for context loading.
      This class will use the configured Springbootapplication entity class as the portal, load the configuration and initialize the spring context;

    2. Can support custom configuration, through environment property setting;
    3. Support different Web environment mode, can be fixed port, random port, several modes of unprovoked.

Keywords
Springrunner, Springboottest, Springbootcontextloader

Four, mock test

The use scenario for Mock testing is when the module (method) being tested relies on external systems (Web services, middleware, or databases).
We need to provide a strategy for quickly validating local implementation logic, which is a Mock, also known as piling.

For example, theA module relies on the B module, and when the B module is unreachable, we Mock the dependent interface.
This allows the test to be completed without the need for a real B module when performing the test.

The Mock component We're going to use here is called Mockito .
Springboot-starter-test comes with a dependency on Mockito, here's a look at the code:

    @Before public void Setupmockmvc () throws Exception {//enable mock @Before public void SETUPMOCKMV        C () throws Exception {//enable mock mockitoannotations.initmocks (this);        Polly = new Pet ();        Polly.settype ("Bird");        Polly.setname ("Polly");        Polly.setdescription ("The rapid Speaker");        Lilei = new Customer ();        Lilei.setname (CUSTOMER);        Set the Mock interface Mockito.when (Datamanager.getpets (Mockito.isa (String.class))). Thenreturn (Arrays.aslist (Polly));        Mockito.when (Datamanager.getcustomer (Mockito.isa (String.class))). Thenreturn (Lilei); With Standalonesetup, specify controller//Because many configurations are not completed automatically due to non-webappliationcontext initialization, and the bean initialization method does not execute MOCKMVC = Moc Kmvcbuilders.standalonesetup (Controller). Setmessageconverters (New Mappingjackson2httpmessageconverter ()). b    Uild ();        } polly = new Pet ();        Polly.settype ("Bird");        Polly.setname ("Polly"); Polly.setdescription ("the Rapid speaker ");        Lilei = new Customer ();        Lilei.setname (CUSTOMER);        Set the Mock interface Mockito.when (Datamanager.getpets (Mockito.isa (String.class))). Thenreturn (Arrays.aslist (Polly));        Mockito.when (Datamanager.getcustomer (Mockito.isa (String.class))). Thenreturn (Lilei); With Standalonesetup, specify controller//Because many configurations are not completed automatically due to non-webappliationcontext initialization, and the bean initialization method does not execute MOCKMVC = Moc Kmvcbuilders.standalonesetup (Controller). Setmessageconverters (New Mappingjackson2httpmessageconverter ()). b    Uild (); }

See, using Mockito, you can achieve the mock effect you want, as follows:

Mockito.when( somemethod ).thenReturn( some thing to return);

However, in the case of mock methods, it is necessary to use the standalonesetup pattern,
Otherwise Mockito will not work.

mockMvc = MockMvcBuilders.standaloneSetup(controller)..

Keywords
Mockito, Mockmvcbuilders

V. Last

The attentive reader will find that the object of unit test mentioned above refers to the smallest unit (method) of software design, but why the springboot part
Are all tests for the API (Controller layer)? Should our unit tests be for a unit that is implemented internally, such as the Dao/service method, or the interface (API Interface)?

The author believes that this is not the absolute good or bad points, the key is the choice.
Unit testing is a concept in the field of software engineering, and software projects are of various types, such as in early software engineering,
There are a lot of programs based on the C/S architecture, the volume of such programs is relatively large, often require a large number of module-level methods for unit testing;

In today's microservices architecture, the API (as a contract) must be tested for each subsystem.
For unit testing of a service, choose Controller or service layer, depending on your cost-effectiveness considerations,

At present, it is a mainstream practice to combine the agile TDD practice with the API testing through unit testing.

Welcome to continue to pay attention to "American Code Master's Tutorial series-springboot", look forward to more exciting content ^-^

Tutorial Series-springboot Unit Test path

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.