GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java library Unit Test Giới thiệu Mockito

Giới thiệu Mockito

Đăng vào 26/03/2019 . Được đăng bởi GP Coder . 14855 Lượt xem . Toàn màn hình

JUnit là một framework dùng cho việc tạo các test case để kiểm thử các method của các đối tượng trong chương trình Java. Nó giúp cho chúng ta có thể đảm bảo đoạn code mà chúng ta viết ra chính xác với những gì chúng ta muốn.

Trong nhiều trường hợp, phương thức cần test của chúng ta gọi đến nhiều phương thức, service khác mà các phương thức này chưa được cài đặt (implement) hoặc tốn nhiều chi phí để thực thi test nhiều lần. Để đảm bảo unit test không phụ thuộc vào nhau, mỗi unit test độc lập được thực thi đúng, chúng ta phải giả định rằng các phương thức được gọi đến đang xử lý đúng. Mockito giúp ta giả lập kết quả của các phương thức liên quan để tập trung viết test cho phương thức hiện tại.

Nội dung

  • 1 Mokito là gì?
  • 2 Phân loại Mock/ Test Double
  • 3 Cài đặt Mockito
  • 4 Ví dụ sử dụng Mockito với JUnit Test

Mokito là gì?

Mockito là một framework hỗ trợ tạo unit test bằng cách sử dụng các đối tượng giả (Mock hay TestDouble) theo cách dễ sử dụng mà không tạo ra “nhiễu” từ các tương tác không liên quan.

Một số thuận lợi khi sử dụng Mockito:

  • Đơn giản: dễ dàng tạo các đối tượng giả và giả lập kết quả, hành vi test.
  • Số lượng API của Mockito không nhiều, nhưng đáp ứng đầy đủ các yêu cầu để giả lập các hành vi test.
  • Tập trung vào test các hành vi cụ thể, giảm thiểu các phiền nhiễu từ các tương tác không liên quan.

Phân loại Mock/ Test Double

Có nhiều trường hợp sử dụng các đối tượng giả, chúng ta có thể phân loại chúng như sau:

  • Dummy object là các đối tượng được di chuyển khắp nơi nhưng không bao được sử dụng thật sự. Thường chúng chỉ được sử dụng để truyền danh sách tham số.
  • Fake object là các đối tượng thật đã được cài đặt một cách đầy đủ, nhưng thường được sử dụng trong môi trường test, không phù hợp cho môi trường thật.
  • Stub object là một chương trình hoặc thành phần giả lập dùng để kiểm thử, nó cung cấp câu trả lời cho các cuộc gọi trong khi kiểm thử. Thông thường nó không đáp lại bất kỳ thứ gì ngoài những gì đã được lập trình cho kiểm thử.
  • Mock object (MO) là một đối tượng, dùng để giả lập hành vi của các class bên ngoài để thực hiện hành vi mà chúng ta mong muốn. Những giả lập này do chúng ta quản lý nên nó đảm bảo chất lượng của những đoạn code mà chúng ta đang viết Unit Test.
  • Spy object : là một trường hợp đặc biệt của Stub và Mock, nó có thể gọi thực sự behavior của dependency hoặc mock một số behavior nếu cần.

Cài đặt Mockito

Để sử dụng Mockito chúng ta cần thêm thư viện này vào project. Với project maven, chúng ta mở file pom.xml và thêm khai báo sau:


<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.25.1</version>
    <scope>test</scope>
</dependency>

Thêm khai báo thư viện JUnit 5 (nếu cần):


<!-- https://mvnrepository.com/artifact/org.mockito/junit-jupiter -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>2.20.0</version>
</dependency>

Ví dụ sử dụng Mockito với JUnit Test

Giả sử chương trình của chúng ta được chia thành 2 lớp: UserDao và UserService.

  • Lớp UserDao thực hiện tạo một user với email được cung cấp vào database và trả về kết quả 1 nếu thêm thành công, ngược lại trả về 0 (trường hợp email đã tồn tại).
  • Lớp UserService nhận yêu cầu từ ứng dụng, sau đó sẽ gọi UserDao để lưu vào database, nếu thêm thành công sẽ thực hiện một số logic như gửi mail và thông báo kết quả về cho người dùng. Trường hợp thêm thất bại sẽ hiển thị một thông báo lỗi.

Mỗi lớp trên được chia cho 2 developer khác nhau cùng thực hiện song song. Để đảm bảo code của mỗi class được thực thi đúng, chúng ta sẽ tiến hành viết Unit test cho nó. Lớp Service muốn viết Unit test được cần phải chờ lớp DAO hoàn thành. Tuy nhiên, điều này không cần thiết và không đúng cho Unit Test. Để tránh phục thuộc lẫn nhau và dễ dàng viết Unit Test, chúng ta sẽ sử dụng Mockito để giả định rằng các behavior của DAO đã thực hiện đúng và chúng ta chỉ việc kiểm thử logic của Service ứng với từng kết quả trả về của DAO.

Chương trình của chúng ta như sau:

UserDao.java


package com.gpcoder.mockito;

public interface UserDao {
	
	boolean createUser(String email);
}

UserService.java


package com.gpcoder.mockito;

public interface UserService {
	
	String createUser(String email);
}

UserServiceImpl.java


package com.gpcoder.mockito;

public class UserServiceImpl implements UserService {

	private UserDao userDao;

	public UserServiceImpl(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public String createUser(String email) {
		boolean result = userDao.createUser(email);
		if (result) {
			// Send an email verify ...
			// Show a success message to end user ...
			return "SUCCESS";
		}
		// Send an error message to end user ...
		return "FAILED";
	}
}

UserServiceImplTest.java


package com.gpcoder.mockito;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

// @RunWith attaches a runner with the test class to initialize the mock data
@RunWith(MockitoJUnitRunner.class)
public class UserServiceImplTest {

	// Create a mock object
	@Mock
	private UserDao userDao;

	private UserService userService;

	@Before
	public void setUp() {
		userService = new UserServiceImpl(userDao);
	}

	@Test
	public void createUser_WhenEmailExisted_ReturnFailed() {
		// Define return value for method createUser()
		Mockito.when(userDao.createUser("existed@gpcoder.com")).thenReturn(false);

		// Use mock in test
		Assert.assertEquals("FAILED", userService.createUser("existed@gpcoder.com"));
	}

	@Test
	public void createUser_WhenEmailNotExisted_ReturnSuccess() {
		// Define return value for method createUser()
		Mockito.when(userDao.createUser("not_existed@gpcoder.com")).thenReturn(true);

		// Use mock in test
		Assert.assertEquals("SUCCESS", userService.createUser("not_existed@gpcoder.com"));
	}
}

Để dễ hiểu ví dụ trên, chúng ta sẽ cùng xem lại từng bước sử dụng Mockito ở class Test:

  • Đầu tiên, chúng ta đánh dấu @RunWith(MockitoJUnitRunner.class) để Mockito xử lý các Annotation của Mockito được áp dụng trong class test này.
  • Một Annotation @Mock được sử dụng để tạo một mock object và inject cho field này.
  • Sử dụng phương thức Mockito.when(T methodCall): dùng để giả lập một lời gọi hàm nào đó được sử dụng bên trong method đang được kiểm thử. Phương thức này thường đi kèm với thenReturn(), thenAnswer(), thenThrow() để chỉ định kết quả trả về. Trong ví dụ này, chúng ta sử dụng thenReturn() để trả về kết quả 0 và 1, ứng với từng trường hợp trả về của DAO.

Lời kết:

Trên đây là một số thông tin cơ bản về Mockito. Trong các bài viết tiếp theo chúng ta sẽ cùng tìm hiểu chi tiết các phương thức được hỗ trợ trong Mockito và các ví dụ chi tiết về từng trường hợp sử dụng.

Tài liệu tham khảo:

  • https://github.com/mockito/mockito/wiki
  • https://github.com/mockito/mockito/wiki/How-to-write-good-tests
  • https://static.javadoc.io/org.mockito/mockito-core/2.25.1/org/mockito/Mockito.html
  • https://www.martinfowler.com/bliki/TestDouble.html
  • https://martinfowler.com/articles/mocksArentStubs.html
  • https://www.toptal.com/java/a-guide-to-everyday-mockito

 

4.5
11
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Unit Test Được gắn thẻ: JUnit, Mockito

JUnit – HTML Report với Surefire maven plugin
Mockito – Annotations

Có thể bạn muốn xem:

  • Mockito – Annotations (28/03/2019)
  • Làm thế nào để lắng nghe các sự kiện mỗi khi một test được thực thi trong JUnit? (23/03/2019)
  • Mockito – Verifying Behavior (03/04/2019)
  • Một số API của JUnit – Assert, Assume, Test Runner (06/03/2019)
  • Tổng hợp các bài viết về Unit Test trong Java (15/04/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (97662 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97348 lượt xem)
  • Giới thiệu Design Patterns (87188 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (85899 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83408 lượt xem)

Nội dung bài viết

  • 1 Mokito là gì?
  • 2 Phân loại Mock/ Test Double
  • 3 Cài đặt Mockito
  • 4 Ví dụ sử dụng Mockito với JUnit Test

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link