Mở tệp mô phỏng Python

Thông thường, phần mềm chúng tôi viết tương tác trực tiếp với những gì chúng tôi gọi là dịch vụ "bẩn". Trong điều khoản của Giáo dân. các dịch vụ quan trọng đối với ứng dụng Python của chúng tôi, nhưng tương tác của chúng có tác dụng phụ có chủ ý nhưng không mong muốn—tức là không mong muốn trong bối cảnh chạy thử nghiệm tự động

Chia sẻ

Chia sẻ

Thông thường, phần mềm chúng tôi viết tương tác trực tiếp với những gì chúng tôi gọi là dịch vụ "bẩn". Trong điều khoản của Giáo dân. các dịch vụ quan trọng đối với ứng dụng Python của chúng tôi, nhưng tương tác của chúng có tác dụng phụ có chủ ý nhưng không mong muốn—tức là không mong muốn trong bối cảnh chạy thử nghiệm tự động

Bởi Naftuli Kay

Chuyên gia đã được xác minh  về Kỹ thuật

Từ việc xây dựng các máy chủ TCP tùy chỉnh đến các ứng dụng tài chính quy mô lớn, bề dày kinh nghiệm của Naftuli khiến anh trở thành nhà phát triển và quản trị hệ thống hàng đầu

def test_default_model_fn[path_exists, mx_load_checkpoint, mx_module, mx_cpu]. sym = Mock[] args = Mock[] aux = Mock[] mx_load_checkpoint. return_value = [sym, args, aux] mx_context = Mock[] mx_cpu. return_value = mx_context data_name = 'foo' data_shape = [1] signature = json. bãi [[{'tên'. data_name, 'hình dạng'. data_shape}]] với bản vá ['sáu. di chuyển. nội trang. open', mock_open[read_data=chữ ký]]. Mặc địnhMXNetInferenceHandler[]. default_model_fn[MODEL_DIR] mx_load_checkpoint. khẳng định_gọi_với[os. con đường. join[MODEL_DIR, 'model'], 0] init_call = call[symbol=sym, context=mx_context, data_names=[data_name], label_names=None] khẳng định init_call trong mx_module. mô hình mock_calls = mx_module. mô hình return_value. trói buộc. khẳng định_gọi_với[for_training=False, data_shapes=[[data_name, data_shape]]] mô hình. set_params. khẳng định_gọi_với[args, aux, allow_missing=True]

Hãy để chúng tôi tạo một hàm lấy json từ tệp và trả về một số dữ liệu. Trong ví dụ này, chúng tôi muốn lấy dữ liệu từ API này và trả về tên của từng hành tinh và nhiệt độ bề mặt của nó trong danh sách

Thay vì tạo một tệp giả, chúng ta có thể giới hạn bản thân trong chuỗi ngắn chỉ với thông tin cần thiết

Nhưng tôi không muốn mở một tập tin thực. Tôi muốn mô phỏng phần mở đầu và nội dung của tệp. Điều này là thanh lịch có thể với

Điều này thay thế việc sử dụng open[]

Điều này hoạt động với cả open[] được gọi trực tiếp như thế này

file = open['file/path', r]

và với một trình quản lý bối cảnh như thế này

with open['file/path', r] as _file:
    # ...

Sử dụng mock_open

Xem để biết thêm chi tiết

Chúng tôi sẽ sử dụng bản vá với tham số

file = open['file/path', r]
0, vì vậy mục tiêu được thay thế bằng một đối tượng mock_open

mock_open[] có một tham số gọi là

file = open['file/path', r]
2 là một chuỗi cho các phương thức
file = open['file/path', r]
3,
file = open['file/path', r]
4 và
file = open['file/path', r]
5 của tệp được mở

Đây là cách giả lập việc mở và đọc tệp bằng trình quản lý ngữ cảnh

with patch['__main__.open', new=mock_open[read_data='Fooooo']] as _file:
    # do your call to path 'foo/bar'
    _file.assert_called_once_with['foo/bar', 'r']

Câu hỏi thường gặp về mã này

Whatafuck là một trình quản lý bối cảnh? . Thêm chi tiết tại đây

Cái quái gì vậy

file = open['file/path', r]
7? . Tuy nhiên, trong ví dụ trên,
file = open['file/path', r]
7 đó chỉ mang tính chất minh họa, bởi vì tôi không chế giễu bất kỳ open[] cụ thể nào. Thêm chi tiết trong

Cái khẳng định đó là cái gì vậy? . Kiểm tra nó ra ở đây

Tôi cá là tôi khá chắc chắn rằng bạn đã sẵn sàng để thử nghiệm phương pháp của chúng tôi

file = open['file/path', r]
9 ngay bây giờ

Vì vậy, hãy kiểm tra mã kiểm tra

import unittest
from unittest.mock import patch, mock_open

from examples.count_lines.file_reader import FileReader


class TestReadFiles[unittest.TestCase]:
    def test_count_lines[self]:
        file_content_mock = """Hello World!!
Hello World is in a file.
A mocked file.
He is not real.
But he think he is.
He doesn't know he is mocked"""
        fake_file_path = 'file/path/mock'

        with patch['examples.count_lines.file_reader.open'.format[__name__],
                   new=mock_open[read_data=file_content_mock]] as _file:
            actual = FileReader[].count_lines[fake_file_path]
            _file.assert_called_once_with[fake_file_path, 'r']

        expected = len[file_content_mock.split['\n']]
        self.assertEqual[expected, actual]

Xem mã nguồn

Viết trên tập tin

Hãy làm đơn giản nhất. Một phương thức nhận một tin nhắn và ghi nó vào một tệp được cung cấp một file_path cụ thể

class FileWriter:
    @staticmethod
    def write[file_path, content]:
        with open[file_path, 'w'] as file:
            file.write[content]

Để giả lập mở tệp và viết nội dung trên đó, chúng ta có thể sử dụng. Mô hình giả cho đối tượng này sẽ tương tự như những gì chúng ta đã thấy trước đây trong , ngoại trừ việc chúng ta không cần chuyển tham số

file = open['file/path', r]
2 trong mock_open[] vì chúng tôi không truy xuất dữ liệu từ tệp

Làm thế nào khẳng định sẽ như thế nào?

Để trả lời câu hỏi này, chúng ta cần tự hỏi mình

Chúng ta muốn kiểm tra điều gì trong chức năng này?

Theo ý kiến ​​ảo tưởng của tôi, một trường hợp kiểm tra tốt sẽ kiểm tra xem một tệp_path cụ thể có được gọi vào ngày _______18_______ hay không, với một chế độ mở cụ thể và liệu một nội dung cụ thể có được ghi trong tệp hay không

Đối tượng thực hiện các xác nhận có thể giúp chúng tôi kiểm tra điều đó. Cái sẽ hữu ích cho chúng ta là

with open['file/path', r] as _file:
    # ...
4

Chúng ta hãy nhìn vào bài kiểm tra?

import unittest
from unittest.mock import patch, mock_open

from examples.write_on_file.file_writer import FileWriter


class TestFileWriter[unittest.TestCase]:
    def test_file_writer[self]:
        fake_file_path = "fake/file/path"
        content = "Message to write on file to be written"
        with patch['examples.write_on_file.file_writer.open', mock_open[]] as mocked_file:
            FileWriter[].write[fake_file_path, content]

            # assert if opened file on write mode 'w'
            mocked_file.assert_called_once_with[fake_file_path, 'w']

            # assert if write[content] was called from the file opened
            # in another words, assert if the specific content was written in file
            mocked_file[].write.assert_called_once_with[content]

Trong thử nghiệm này, chúng tôi mô phỏng việc mở tệp bằng trình quản lý bối cảnh. Biến

with open['file/path', r] as _file:
    # ...
5 là tệp được mở giả định

Mô hình mở là gì?

mock_open được dùng để trả về dữ liệu thử nghiệm . Tùy thuộc vào phiên bản Python, chúng tôi mô phỏng open tích hợp sẵn. Ví dụ, trong Python 2, nó được gọi là __builtin__. mở trong khi ở Python 3, nó được gọi là nội trang. mở.

Sự khác biệt giữa giả và MagicMock là gì?

Vậy sự khác biệt giữa chúng là gì? . Nó chứa tất cả các phương pháp ma thuật được tạo sẵn và sẵn sàng để sử dụng [e. g. __str__ , __len__ , v.v. ]. Do đó, bạn nên sử dụng MagicMock khi cần các phương thức ma thuật và Mock nếu không cần. MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use [e.g. __str__ , __len__ , etc.]. Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.

Bạn có thể thử nhập bằng Python không?

Trình mô phỏng nhập khẩu Python cung cấp một cách dễ dàng để nhập mô-đun và mô phỏng các thành phần phụ thuộc của mô-đun theo cách riêng biệt .

Python mô phỏng hoạt động như thế nào?

mock là một thư viện để thử nghiệm trong Python. Nó cho phép bạn thay thế các phần của hệ thống đang thử nghiệm bằng các đối tượng giả và đưa ra xác nhận về cách chúng được sử dụng . đơn vị nhất. mock cung cấp một lớp Mock cốt lõi loại bỏ nhu cầu tạo một loạt sơ khai trong bộ thử nghiệm của bạn.

Chủ Đề