Typical examples of junit and Mockito unit tests

Source: Internet
Author: User
Tags throw exception

The importance of unit testing does not need to be redundant, but unit testing can also be difficult, one of which is how to create dependencies. Imagine our common server-side tiered architecture, the data Access layer DAO, the business layer, and the web layer, and want the unit test business layer, we need to rely on the DAO layer to provide data support, the DAO layer is dependent on the database, the database needs Shema and data. In order to test the business logic, it is necessary to prepare so many things, think about the trouble, unit test enthusiasm also minus half. The solution to this problem is the mock technique, which simulates the behavior of the component being relied on. Let's talk about unit tests .

Unit test is simply the test of class, the test object is a class, the test content is the correctness of class logic, here to emphasize that the test content only focus on the logic of the test class itself, the class of the test depends on the logic of the class, should be the other unit test to cover. The following figure is a simple schematic:

Unit tests only focus on the logic of target. If there is no target Dependency, then of course better, direct testing. What if there is target dependency? Sometimes it's easy to build target dependency, new object. What about the DAO dependency class to the beginning? It's OK to create a database, initialize the table structure and data, but these are not related to the correctness of the business layer we want to test.

A more eco-friendly approach is to mock DAO classes. But how to mock. Mock what content. There are many good mock tools in the Java world, such as Easymock, Jmock, and Mockito, which can be used to simplify our mock work. This article only discusses Mockito. As for the question of what to mock, my understanding is the behavior of mock classes, that is, the Method,value object of the class is created directly. The method of a class is roughly divided into the following: Method name method input parameter method output return value method Exception method EXECUTE statement

The name of method certainly cannot change, there is no mock argument. Everything else can be mock. Dao Mock Example

Prepare entity and DAO interfaces first:

public class User {
    private Long ID;
    private String name;

    Public Long GetId () {return
        ID;
    }
    public void SetId (Long id) {
        this.id = ID;
    }
    Public String GetName () {return
        name;
    }
    public void SetName (String name) {
        this.name = name;
    }
}

Public interface Userdao {
    /**
     * Add user
    /

    void Insertuser /**
     * Inquiry User * *
    queryuser (Long ID);

Here is the business service and implementation, TDD is the practice of first unittest after the implementation of the service, the concern is not
It's TDD, it's a mock, and it's not going to take a moment.

Public interface UserService {/** * Create new user */void CreateNewUser (user user) throws Excep
    tion;

    public class Userserviceimpl implements UserService {private Userdao Userdao; public void CreateNewUser (user user) throws Exception {//Parameter check if (user = null | | User.getid () = NULL | |
        IsEmpty (User.getname ()) {throw new illegalargumentexception ();
        //See if duplicate data Long id = User.getid ();
        User Dbuser = userdao.queryuser (ID);
        if (dbuser!= null) {throw new Exception ("User already exists");
        try {userdao.insertuser (dbuser);
        catch (Exception e) {//Hide database exception, throw service exception throw new Exception ("Database statement execution failed", e); } Private Boolean IsEmpty (String str) {if (str = NULL | | Str.trim (). Length () = 0) {Retu
        RN true;
    return false; public void Setuserdao (useRdao Userdao) {This.userdao = Userdao;
 }
}

Start Unit test:

Import Org.junit.Test;
Import Org.mockito.invocation.InvocationOnMock;

Import Org.mockito.stubbing.Answer;

Import static org.mockito.mockito.*;

Import java.sql.SQLException;  public class Userservicetest {@Test (expected = illegalargumentexception.class) public void Testnulluser () throws

        Exception {UserService userservice = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);

        ((Userserviceimpl) userservice). Setuserdao (Userdao);
    Userservice.createnewuser (NULL); @Test (expected = illegalargumentexception.class) public void Testnulluserid () throws Exception {Userse

        Rvice userservice = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);

        ((Userserviceimpl) userservice). Setuserdao (Userdao);
        User user = new user ();
        User.setid (NULL);
    Userservice.createnewuser (user); } @Test (expected = Illegalargumentexception.class) PUBlic void Testnullusername () throws Exception {UserService userservice = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);

        ((Userserviceimpl) userservice). Setuserdao (Userdao);
        User user = new user ();
        User.setid (1L);
        User.setname ("");
    Userservice.createnewuser (user); @Test (expected = exception.class) public void Testcreateexistuser () throws Exception {UserService user

        Service = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);
        User Returnuser = new user ();
        Returnuser.setid (1L);
        Returnuser.setname ("Vikey");
        When (Userdao.queryuser (1L)). Thenreturn (Returnuser);

        ((Userserviceimpl) userservice). Setuserdao (Userdao);
        User user = new user ();
        User.setid (1L);
        User.setname ("Vikey");
    Userservice.createnewuser (user); @Test (expected = exception.class) public void tesTcreateuserondatabaseexception () throws Exception {UserService userservice = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);
        Dothrow (New SQLException ("SQL isn't valid"). When (Userdao). Insertuser (Any (user.class));

        ((Userserviceimpl) userservice). Setuserdao (Userdao);
        User user = new user ();
        User.setid (1L);
        User.setname ("Vikey");
    Userservice.createnewuser (user);

        @Test public void Testcreateuser () throws Exception {UserService userservice = new Userserviceimpl ();
        Create mock Userdao Userdao = mock (userdao.class);
                Doanswer (New answer<void> () {public Void Answer (Invocationonmock invocation) throws Throwable {
                System.out.println ("Insert Data into User table");
            return null;
        . When (Userdao). Insertuser (Any (user.class)); ((Userserviceimpl) userservice). Setuserdao (Userdao);
        User user = new user ();
        User.setid (1L);
        User.setname ("Vikey");
    Userservice.createnewuser (user);
 }
}

The first three test cases were tested for the service's handling of illegal input parameters, with no Userdao, no mocks. The 4th Test case test is the processing logic of the service, UserService how to deal with the new existing user problem, we expect the error. To determine whether the user exists, need to use the Userdao.queryuser interface, so we mock the Queryuser method. Returns a user object when the parameter is 1L. The 5th test case tests the case of a DAO throw exception. The 6th test case tests the normal processing situation, Doanswer only shows the use of no return value method, which can not be written. Conclusion

Mockito is powerful and has the function of memorizing method calls, but I don't think unittest should focus too much on mocks, but target. Mockito syntax is very strange, and our usual contact with the Java code is not, familiar with it will find its API very beautiful. Reference Links The classical-Mockito design analysis of the anti-pattern of the design idea behind the Mockito author's explanation

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.