久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

模擬類方法中使用的 open() 函數

Mock open() function used in a class method(模擬類方法中使用的 open() 函數)
本文介紹了模擬類方法中使用的 open() 函數的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我試圖模擬在我的類的方法中使用的 open 函數.我發現這個線程 如何模擬一個在 with 語句中使用的 open(使用 Python 中的 Mock 框架)? 但無法解決我的問題.unittest 文檔還顯示了一個解決方案,它也沒有模擬我打開的 https://docs.python.org/3/library/unittest.mock-examples.html#patch-decorators

I tried to mock the open function used in a method of my class. I found this thread How do I mock an open used in a with statement (using the Mock framework in Python)? but could not solve my issue. Also the unittest documention shows a solution which also didn't mock my open https://docs.python.org/3/library/unittest.mock-examples.html#patch-decorators

這是我的類,其中使用了open函數的方法:

This is my class with the method where the open function is used:

#__init.py__

import json

class MyClass:

    def save_data_to_file(self, data):
        with open('/tmp/data.json', 'w') as file:
            json.dump(data, file)
...
mc = MyClass()

現在我找到了一些不同的解決方案.這是我的測試:

Now I found a little different solution. This is my test:

#save_to_file_test.py

from mymodule import MyClass
from mock import mock_open, patch
import ast

class SaveToFileTest(unittest.TestCase):

    def setUp(self):
        self.mc = MyClass()
        self.data = [
            {'id': 5414470, 'name': 'peter'},
            {'id': 5414472, 'name': 'tom'},
            {'id': 5414232, 'name': 'pit'},
        ]

    def test_save_data_to_file(self):
        m = mock_open()
        with patch('mymodule.open', m, create=True):
            self.mc.save_data_to_file(self.data)
            string = ''
            for call in m.return_value.write.mock_calls:
                string += (call[1][0])
            list = ast.literal_eval(string)
            assertEquals = (list, self.data)

我不確定這是否是測試應寫入文件的內容的最佳方法.當我測試 mock_calls(call_args_list 相同)時,這是傳遞給文件句柄的參數.歡迎任何意見、改進和建議.

I'm not sure if this is the best way to test the content which should be written to a file. When I test the mock_calls (call_args_list is the same) this are the arguments which are passed to the file handle. Any advice, improvements and suggestions are welcome.

推薦答案

TL;DR

您的問題的核心是您應該還模擬 json.dump 以便能夠正確測試將要寫入文件的數據.在對您的測試方法進行一些重要調整之前,我實際上很難運行您的代碼.

TL;DR

The heart of your problem is that you should be also mocking json.dump to be able to properly test the data that is going to be written to your file. I actually had a hard time running your code until a few important adjustments were made to your test method.

  • 使用 builtins.open 而不是 mymmodule.open
  • 進行模擬
  • 你在一個上下文管理器中,所以你應該檢查 m.return_value.__enter__.write,但是你實際上是從 json.dump 調用 write 的,這是調用 write 的地方.(以下有關建議解決方案的詳細信息)
  • 您還應該模擬 json.dump 以簡單地驗證它是用您的數據調用的
  • Mock with builtins.open and not mymmodule.open
  • You are in a context manager, so you should be checking m.return_value.__enter__.write, however you are actually calling the write from json.dump which is where the write will be called. (Details below on a suggested solution)
  • You should also mock json.dump to simply validate it is called with your data

簡而言之,有了上面提到的問題,方法可以重寫為:

In short, with the issues mentioned above, the method can be re-written as:

以下所有內容的詳細信息

def test_save_data_to_file(self):
    with patch('builtins.open', new_callable=mock_open()) as m:
        with patch('json.dump') as m_json:
            self.mc.save_data_to_file(self.data)

            # simple assertion that your open was called 
            m.assert_called_with('/tmp/data.json', 'w')

            # assert that you called m_json with your data
            m_json.assert_called_with(self.data, m.return_value)

詳細說明

要專注于我在您的代碼中看到的問題,我強烈建議您做的第一件事,因為 open 是內置的,是從內置模擬,此外,您可以為自己節省一行通過使用 new_callableas 來編寫代碼,所以你可以簡單地這樣做:

Detailed Explanation

To focus on the problems I see in your code, the first thing I strongly suggest doing, since open is a builtin, is to mock from builtins, furthermore, you can save yourself a line of code by making use of new_callable and as, so you can simply do this:

with patch('builtins.open', new_callable=mock_open()) as m:

我在您的代碼中看到的下一個問題是我在運行此代碼時遇到了問題,直到您開始循環調用時我實際進行了以下調整:

The next problem that I see with your code as I had trouble running this until I actually made the following adjustment when you started looping over your calls:

m.return_value.__enter__.return_value.write.mock_calls

要剖析它,您必須記住的是您的方法使用的是上下文管理器.在使用上下文管理器時,您的寫入工作實際上將在您的 __enter__ 方法中完成.所以,從你的mreturn_value中,你想得到__enter__的return_value.

To dissect that, what you have to keep in mind is that your method is using a context manager. In using a context manager, the work of your write will actually be done inside your __enter__ method. So, from the return_value of your m, you want to then get the return_value of __enter__.

但是,這將我們帶到了您要測試的問題的核心.由于 json.dump 在寫入文件時的工作方式,您在檢查代碼后寫入的 mock_calls 實際上如下所示:

However, this brings us to the heart of the problem with what you are trying to test. Because of how the json.dump works when writing to the file, your mock_calls for your write after inspecting the code, will actually look like this:

<MagicMock name='open().write' id='4348414496'>
call('[')
call('{')
call('"name"')
call(': ')
call('"peter"')
call(', ')
call('"id"')
call(': ')
call('5414470')
call('}')
call(', ')
call('{')
call('"name"')
call(': ')
call('"tom"')
call(', ')
call('"id"')
call(': ')
call('5414472')
call('}')
call(', ')
call('{')
call('"name"')
call(': ')
call('"pit"')
call(', ')
call('"id"')
call(': ')
call('5414232')
call('}')
call(']')
call.__str__()

測試起來不會很有趣.因此,這將我們帶到您可以嘗試的下一個解決方案;模擬 json.dump.

That is not going to be fun to test. So, this brings us to the next solution you can try out; Mock json.dump.

你不應該測試 json.dump,你應該測試用正確的參數調用它.話雖如此,您可以按照類似的方式進行模擬并執行以下操作:

You shouldn't be testing json.dump, you should be testing calling it with the right parameters. With that being said, you can follow similar fashion with your mocking and do something like this:

with patch('json.dump') as m_json:

現在,有了它,您可以顯著簡化您的測試代碼,以簡單地驗證該方法是否被您正在測試的數據調用.所以,有了它,當你把它們放在一起時,你會得到這樣的東西:

Now, with that, you can significantly simplify your test code, to simply validate that the method gets called with your data that you are testing with. So, with that, when you put it all together, you will have something like this:

def test_save_data_to_file(self):
    with patch('builtins.open', new_callable=mock_open()) as m:
        with patch('json.dump') as m_json:
            self.mc.save_data_to_file(self.data)

            # simple assertion that your open was called 
            m.assert_called_with('/tmp/data.json', 'w')

            # assert that you called m_json with your data
            m_json.assert_called_with(self.data, m.return_value.__enter__.return_value)

如果您有興趣進一步重構以使您的測試方法更簡潔,您還可以將補丁設置為裝飾器,讓您的代碼更簡潔:

If you're interested in further refactoring to make your test method a bit cleaner, you could also set up your patching as a decorator, leaving your code cleaner inside the method:

@patch('json.dump')
@patch('builtins.open', new_callable=mock_open())
def test_save_data_to_file(self, m, m_json):
    self.mc.save_data_to_file(self.data)

    # simple assertion that your open was called
    m.assert_called_with('/tmp/data.json', 'w')

    # assert that you called m_json with your data
    m_json.assert_called_with(self.data, m.return_value.__enter__.return_value)

檢查是您最好的朋友,查看在哪些步驟調用了哪些方法,以進一步幫助測試.祝你好運.

Inspecting is your best friend here, to see what methods are being called at what steps, to further help with the testing. Good luck.

這篇關于模擬類方法中使用的 open() 函數的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Python 3 Float Decimal Points/Precision(Python 3 浮點小數點/精度)
Converting Float to Dollars and Cents(將浮點數轉換為美元和美分)
What are some possible calculations with numpy or scipy that can return a NaN?(numpy 或 scipy 有哪些可能的計算可以返回 NaN?)
Python float to ratio(Python浮動比率)
How to manage division of huge numbers in Python?(如何在 Python 中管理大量數字的除法?)
mean from pandas and numpy differ(pandas 和 numpy 的意思不同)
主站蜘蛛池模板: 日韩高清国产一区在线 | 日韩在线免费观看视频 | 国产精品自产av一区二区三区 | 欧美日韩精品久久久免费观看 | 久久99精品久久久久久国产越南 | 久久久久国产精品一区三寸 | 丁香久久 | 欧美激情国产日韩精品一区18 | 91精品久久久久久久 | 久久久久国| 中文字幕不卡视频在线观看 | 日韩精品在线观看网站 | 521av网站 | 欧美一区二区另类 | 日韩二三区| 在线观看视频一区二区三区 | 国产成人免费视频网站视频社区 | a国产视频| 中文字幕亚洲在线 | 国产成人精品区一区二区不卡 | 欧美aⅴ在线观看 | 久久只有精品 | 天天操夜夜爽 | 久久久精 | 青青久视频 | 欧美日韩久久精品 | 欧美4p | 亚洲精品3 | 国产精品亚洲一区二区三区在线 | 欧美1区| 午夜在线影院 | 四虎网站在线观看 | 欧美精品影院 | 欧美一级欧美一级在线播放 | 亚洲视频一区在线观看 | 国产一区二区日韩 | 中文字幕一区二区三 | 在线成人免费视频 | 亚洲视频一区在线播放 | 精品国产乱码久久久久久久久 | 成人免费精品视频 |