PYTHON UNIT TESTING
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Sử dụng Mock trong Unittest của Python

Không phải lúc nào mình cũng có thể kiểm tra mã nguồn một cách trực tiếp, đặc biệt khi mã nguồn phụ thuộc vào các yếu tố bên ngoài như hệ thống, mạng, hoặc các I/O operation. Để giải quyết vấn đề này, Python cung cấp mô-đun unittest.mock với lớp Mock, giúp mình mô phỏng các đối tượng thực tế và kiểm tra mã nguồn một cách độc lập và hiệu quả hơn. Trong bài viết này, mình sẽ tìm hiểu về lớp Mock của unittest.mock, cách sử dụng nó để mô phỏng các đối tượng khác, và lợi ích của việc sử dụng Mock trong việc kiểm tra mã nguồn Python.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Giới thiệu về lớp Mock của unittest trong Python

Mocks mô phỏng hành vi của các đối tượng thực tế. Để kiểm tra một đối tượng phụ thuộc vào các đối tượng khác một cách độc lập, bạn sử dụng các đối tượng mock để mô phỏng các đối tượng thực.

Để mô phỏng các đối tượng, bạn sử dụng mô-đun unittest.mock. Mô-đun này cung cấp lớp Mock cho phép bạn mô phỏng các đối tượng khác. Nó cũng cung cấp lớp MagicMock, là một lớp con của Mock. Ngoài các phương thức và thuộc tính của lớp Mock, lớp MagicMock còn có các triển khai của tất cả các phương thức đặc biệt như __str____repr__.

Xem ví dụ sau:

Bài viết này được đăng tại [free tuts .net]

from unittest.mock import Mock

# tạo một đối tượng mock mới
mock = Mock()

# mô phỏng hàm api
mock.api.return_value = {
    'id': 1,
    'message': 'hello'
}
# gọi hàm api
print(mock.api())

Kết quả:

{'id': 1, 'message': 'hello'}

Cách hoạt động:

Đầu tiên, import lớp Mock từ mô-đun unittest.mock:

from unittest.mock import Mock

Thứ hai, tạo một thể hiện mới của lớp Mock:

mock = Mock()

Thứ ba, mô phỏng hàm api() và gán giá trị trả về của nó là một từ điển:

mock.api.return_value = {
    'id': 1,
    'message': 'hello'
}

Cuối cùng, gọi hàm api() từ đối tượng mock. Nó sẽ trả về giá trị đã gán:

print(mock.api())

Trong ví dụ này, mình có hai đối tượng mock: mockmock.api.

Thêm câu lệnh print() vào chương trình để xem cách nó hoạt động:

from unittest.mock import Mock

# tạo một đối tượng mock mới
mock = Mock()
print(mock)

# mô phỏng hàm api
mock.api.return_value = {
    'id': 1,
    'message': 'hello'
}
print(mock.api)

# gọi hàm api
print(mock.api())

Kết quả:

<Mock id='1830094470496'>
<Mock name='mock.api' id='1830100086416'>
{'id': 1, 'message': 'hello'}

Kết quả cho thấy hai đối tượng Mock.

Tóm lại, nếu bạn gán một thuộc tính không tồn tại trên đối tượng Mock, Python sẽ trả về một đối tượng mock mới. Nhờ vào tính năng này, bạn có thể sử dụng lớp Mock để mô phỏng bất kỳ đối tượng nào bạn muốn.

Khi nào sử dụng mock của unittest trong Python

Đây là những trường hợp bạn nên xem xét sử dụng mock:

  • Các lệnh gọi hệ thống
  • Mạng
  • Hoạt động I/O
  • Đồng hồ & thời gian, múi giờ
  • Hoặc các trường hợp khác mà kết quả không thể dự đoán trước

Tại sao sử dụng mock của unittest trong Python

Lợi ích của mock bao gồm:

  • Tăng tốc độ kiểm tra
  • Loại trừ các yếu tố dư thừa bên ngoài
  • Làm cho các kết quả không thể đoán trước trở nên có thể đoán trước

Ví dụ về sử dụng Mock trong Python Unittest

Giả sử bạn có một mô-đun gọi là odometer.py:

from random import randint

def speed():
    return randint(40, 120)

def alert():
    s = speed()
    if s < 60 or s > 100:
        return True
    return False

Trong mô-đun sensor.py:

  • Hàm speed() trả về tốc độ hiện tại của một phương tiện. Nó trả về một giá trị ngẫu nhiên giữa 40 và 120. Trong thế giới thực, hàm này sẽ đọc dữ liệu từ đồng hồ đo tốc độ.
  • Hàm alert() trả về True nếu tốc độ hiện tại thấp hơn 60 km/h và cao hơn 100 km/h. Hàm alert() sử dụng hàm speed() để lấy tốc độ hiện tại.

Screenshot 202024 06 17 20162333 png

Sẽ rất khó kiểm tra hàm alert() vì giá trị trả về bởi hàm speed() là khác nhau. Để giải quyết, bạn có thể sử dụng lớp Mock.

Sau đây là cách tạo mô-đun kiểm tra test_odometer.py để kiểm tra hàm alert():

import unittest
from unittest.mock import Mock
import odometer

class TestOdometer(unittest.TestCase):
    def test_alert_normal(self):
        odometer.speed = Mock()
        odometer.speed.return_value = 70
        self.assertFalse(odometer.alert())

    def test_alert_overspeed(self):
        odometer.speed = Mock()
        odometer.speed.return_value = 100
        self.assertFalse(odometer.alert())

    def test_alert_underspeed(self):
        odometer.speed = Mock()
        odometer.speed.return_value = 59
        self.assertTrue(odometer.alert())

Chạy kiểm tra:

Screenshot 202024 06 17 20162347 png

python -m unittest test_odometer.py -v

Kết quả:

test_alert_normal (test_odometer.TestOdometer) ... ok
test_alert_overspeed (test_odometer.TestOdometer) ... ok
test_alert_underspeed (test_odometer.TestOdometer) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

Kết bài

Việc sử dụng lớp Mock của mô-đun unittest.mock trong Python giúp bạn dễ dàng mô phỏng các đối tượng khác để kiểm tra mã nguồn một cách độc lập và hiệu quả. Nhờ vào các tính năng mạnh mẽ của lớp Mock, bạn có thể loại bỏ các yếu tố không thể đoán trước và tăng tốc độ kiểm tra. Hy vọng rằng qua bài viết này, bạn đã hiểu rõ hơn về cách sử dụng mock để nâng cao chất lượng và độ tin cậy của mã nguồn Python.

Cùng chuyên mục:

Cách thêm Progress Bar trong Python với chỉ một dòng Code

Cách thêm Progress Bar trong Python với chỉ một dòng Code

Toán tử Walrus Operator- Tính năng mới trong Python 3.8

Toán tử Walrus Operator- Tính năng mới trong Python 3.8

Cách nạp dữ liệu Machine Learning từ File trong Python

Cách nạp dữ liệu Machine Learning từ File trong Python

Hướng dẫn sử dụng Google Sheets API với Python

Hướng dẫn sử dụng Google Sheets API với Python

Xây dựng  web Python tự động hóa Twitter | Flask, Heroku, Twitter API & Google Sheets API

Xây dựng web Python tự động hóa Twitter | Flask, Heroku, Twitter API & Google Sheets API

Xây dựng Web Machine Learning đẹp mắt với Streamlit và Scikit-learn trong Python

Xây dựng Web Machine Learning đẹp mắt với Streamlit và Scikit-learn trong Python

Hướng dẫn tạo Chatbot đơn giản bằng PyTorch

Hướng dẫn tạo Chatbot đơn giản bằng PyTorch

11 mẹo và thủ thuật để viết Code Python hiệu quả hơn

11 mẹo và thủ thuật để viết Code Python hiệu quả hơn

Hướng dẫn làm ứng dụng TODO với Flask dành cho người mới bắt đầu trong Python

Hướng dẫn làm ứng dụng TODO với Flask dành cho người mới bắt đầu trong Python

Hướng dẫn viết Snake Game bằng Python

Hướng dẫn viết Snake Game bằng Python

Cách sử dụng chế độ interactive trong Python

Cách sử dụng chế độ interactive trong Python

Cách sử dụng Python Debugger với hàm breakpoint()

Cách sử dụng Python Debugger với hàm breakpoint()

Xây dựng ứng dụng Web Style Transfer với PyTorch và Streamlit

Xây dựng ứng dụng Web Style Transfer với PyTorch và Streamlit

Cách cài đặt Jupyter Notebook trong môi trường Conda và thêm Kernel

Cách cài đặt Jupyter Notebook trong môi trường Conda và thêm Kernel

Hướng dẫn xây dựng ứng dụng dự đoán giá cổ phiếu bằng Python

Hướng dẫn xây dựng ứng dụng dự đoán giá cổ phiếu bằng Python

Hướng dẫn tạo ứng dụng AI hội thoại với NVIDIA Jarvis trong Python

Hướng dẫn tạo ứng dụng AI hội thoại với NVIDIA Jarvis trong Python

Hỗ trợ Async trong Django 3.1

Hỗ trợ Async trong Django 3.1

8 mẹo tái cấu trúc Python giúp mã sạch hơn và Pythonic

8 mẹo tái cấu trúc Python giúp mã sạch hơn và Pythonic

Ý nghĩa của if __name__ ==

Ý nghĩa của if __name__ == "__main__" trong Python

Cách xóa phần tử trong danh sách Python

Cách xóa phần tử trong danh sách Python

Top