মক ব্যবহার করে কোনও ফাংশন / পদ্ধতি বলা হয়নি


131

আমি আমার অ্যাপ্লিকেশন পরীক্ষা করার জন্য মক লাইব্রেরিটি ব্যবহার করছি, তবে আমি দৃ as়ভাবে বলতে চাই যে কোনও ফাংশন ডাকা হয়নি। নকল ডক্সের মত পদ্ধতি সম্পর্কে কথা বলতে mock.assert_called_withএবং mock.assert_called_once_with, কিন্তু আমি ভালো কিছু খুঁজে পান না mock.assert_not_calledবা উপহাস যাচাই এর সাথে সম্পর্কিত কিছু ছিল বলা

আমি নীচের মতো কিছু নিয়ে যেতে পারি, যদিও এটি শীতল বা পাইথোনিক বলে মনে হচ্ছে না:

def test_something:
    # some actions
    with patch('something') as my_var:
        try:
            # args are not important. func should never be called in this test
            my_var.assert_called_with(some, args)
        except AssertionError:
            pass  # this error being raised means it's ok
    # other stuff

কোনও ধারণা কীভাবে এটি সম্পাদন করবেন?


@ অহমেট তার উত্তরে ইঙ্গিত করার সাথে সাথে ব্যাকপোর্টেও ( ডক্টস.পাইথন.আর
মার্টিন

উত্তর:


144

এটি আপনার ক্ষেত্রে কাজ করা উচিত;

assert not my_var.called, 'method should not have been called'

নমুনা;

>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been

এই উত্তরটির কি জ্যাঙ্গো দরকার? আমি একটি ত্রুটি পাচ্ছি:AttributeError: MockCallable instance has no attribute 'called'
নাথন আর্থার

@ নাথান আর্থার এইচএম, আমি মনে করি না, ম্যাকোএসের পরে sudo easy_install -U mockএবং পরে from mock import Mock, উপরোক্ত কোনও বাধা ছাড়াই চলে। জ্যাঙ্গো কখনই ইনস্টল করা হয়নি :)
জোছিম ইসাকসন

হুম। অদ্ভুত জিনিস. আমি পাইথন ২.7.১ from mock import Mockচালাচ্ছি এবং আমার পরীক্ষার জন্য ইউনিটেস্ট এবং পাইথন মক ০.০.০ ব্যবহার করছি। শব্দটির কোনওটিই সমস্যাযুক্ত?
নাথন আর্থার

আমি অন্য মডিউল থেকে কলযোগ্য শ্রেণিকে উপহাস করছি, সুতরাং দেখে মনে হচ্ছে module_to_test.another_module.class = mock.Mock(), আপনি কি নিশ্চিত করতে পারেন যে এটি বিভিন্ন পরীক্ষার কেসগুলিতে কলগুলি মনে রাখে না (ইউনিটেস্ট.টেষ্টক্যাস উদাহরণস্বরূপ)? আমি মনে করি এই ক্ষেত্রে কল গণনাটি পুনরায় সেট হচ্ছে না
0xc0de

66

যদিও একটি পুরানো প্রশ্ন, আমি যুক্ত করতে চাই যে বর্তমানে mockলাইব্রেরি (ইউনিটএস্ট.মকের ব্যাকপোর্ট) assert_not_calledপদ্ধতি সমর্থন করে ।

শুধু আপনার আপগ্রেড করুন;

pip install mock --upgrade


29

আপনি calledবৈশিষ্ট্যটি পরীক্ষা করতে পারেন , তবে যদি আপনার দৃ f়তা ব্যর্থ হয়, তবে পরবর্তী জিনিসটি আপনি অপ্রত্যাশিত কল সম্পর্কে কিছু জানতে চান , তাই আপনি সেই তথ্যটি শুরু থেকেই প্রদর্শিত হওয়ার ব্যবস্থা করতে পারেন। ব্যবহার করে unittest, আপনি call_args_listপরিবর্তে এর বিষয়বস্তু পরীক্ষা করতে পারেন :

self.assertItemsEqual(my_var.call_args_list, [])

যখন এটি ব্যর্থ হয়, এটি এই জাতীয় বার্তা দেয়:

AssertionError: এলিমেন্ট গণনা সমান ছিল না:
প্রথমটির 0 আছে, দ্বিতীয়টির 1 আছে: কল ('প্রথম যুক্তি', 4)

14

আপনি যখন ইনহেরিট বর্গ ব্যবহার পরীক্ষা unittest.TestCase আপনি কেবল মত পদ্ধতি ব্যবহার করতে পারেন:

  • assertTrue
  • assertFalse
  • assertEqual

এবং অনুরূপ ( পাইথন ডকুমেন্টেশনে) আপনি খুঁজে পান)

আপনার উদাহরণে আমরা কেবলমাত্র যদি মক_মোথডা.কলিট সম্পত্তিটি মিথ্যা হয় তবে আমরা দৃ that়ভাবে বলতে পারি যে এর অর্থ এই পদ্ধতিটি বলা হয়নি।

import unittest
from unittest import mock

import my_module

class A(unittest.TestCase):
    def setUp(self):
        self.message = "Method should not be called. Called {times} times!"

    @mock.patch("my_module.method_to_mock")
    def test(self, mock_method):
        my_module.method_to_mock()

        self.assertFalse(mock_method.called,
                         self.message.format(times=mock_method.call_count))

11

সঙ্গে python >= 3.5আপনি ব্যবহার করতে পারেন mock_object.assert_not_called()


1

অন্যান্য উত্তরগুলি বিবেচনা করে, @ রব-কেনেডি ছাড়া আর কেউই এই বিষয়ে কথা বলেনিcall_args_list

এটি একটি শক্তিশালী সরঞ্জাম যার জন্য আপনি ঠিক এর বিপরীতটি বাস্তবায়ন করতে পারেন MagicMock.assert_called_with()

call_args_listcallবস্তুর একটি তালিকা । প্রতিটি callবস্তু একটি উপহাসযুক্ত কল করার জন্য করা কলকে উপস্থাপন করে।

>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.call_args_list
[]
>>> m(42)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42)]
>>> m(42, 30)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42), call(42, 30)]

কোনও callবস্তু গ্রহণ করা সহজ, যেহেতু আপনি এটির দৈর্ঘ্য 2 এর একটি দ্বিগুণের সাথে তুলনা করতে পারেন যেখানে প্রথম উপাদানটি সম্পর্কিত কলটির সমস্ত অবস্থানগত আর্গুমেন্ট সমেত একটি টুপল, যখন দ্বিতীয় উপাদানটি মূলশব্দ যুক্তিগুলির একটি অভিধান।

>>> ((42,),) in m.call_args_list
True
>>> m(42, foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((42,), {'foo': 'bar'}) in m.call_args_list
True
>>> m(foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((), {'foo': 'bar'}) in m.call_args_list
True

সুতরাং, ওপির নির্দিষ্ট সমস্যাটি সমাধানের একটি উপায়

def test_something():
    with patch('something') as my_var:
        assert ((some, args),) not in my_var.call_args_list

মনে রাখবেন যে এই উপায়ে, কোনও উপহাসযুক্ত কলটি কল করা হয়েছে কিনা তা পরীক্ষা করার পরিবর্তে MagicMock.called , আপনি এখন এটি নির্দিষ্ট আর্গুমেন্টের সাহায্যে কল করা হয়েছে কিনা তা পরীক্ষা করে দেখতে পারেন।

এটি দরকারী। বলুন যে আপনি কোনও ফাংশন পরীক্ষা করতে চান যা একটি তালিকা গ্রহণ করে এবং অন্য ফাংশনটিতে কল করে,compute() কেবলমাত্র তালিকাটির প্রতিটি মানের জন্য যদি তারা একটি নির্দিষ্ট শর্তটি পূরণ করে তবে।

আপনি এখন উপহাস করতে পারেন computeএবং পরীক্ষা করতে পারেন যদি এটির কোনও মূল্য দেওয়া হয় তবে অন্যের কাছে নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.