24Mar, 2022
Language blog :
Thai
Share blog : 
24 March, 2022
Thai

Mock Object ในภาษา Python

By

4 mins read
Mock Object ในภาษา Python

Mock Object คืออะไร

Mock Object คือวิธีการที่ใช้ในการกำหนดพฤติกรรม Object เพื่อให้ได้ผลลัพธ์ที่ใช้ในการทำ Unit Test ตาม Environment ที่ต้องการ โดยจะเป็นการสมมุติว่า ฟังก์ชันทำงานถูกต้องและจะทำการ Mock ข้อมูลขึ้นมาเพื่อใช้ทำการทดสอบ

สาเหตุที่ต้องใช้หลัก ๆ  Python Mock Object เพื่อควบคุมสิ่งที่เกิดขึ้นในการทำ UnitTest

ในบางครั้ง ต้องทำการทดสอบฟังก์ชัน เช่น get_coin_price ซึ่งจะทำการแสดงข้อมูลราคาของเหรียญ โดยดึงจากฐานข้อมูล ซื่งถ้าใช้ฐานข้อมูลจริงในบางครั้งผลลัพธ์ที่ได้อาจจะไม่ถูกต้อง เพราะฐานข้อมูลอาจจะมีการเปลี่ยนแปลงซึ่งยากที่จะควบคุม ดังนั้น จึงเป็นสาเหตุที่ดีกว่าที่จะทำการทดสอบโค้ดในสถานการที่ควบคุมได้ โดยการใช้ Mock Object เพื่อทำการจะให้ฟังก์ชันได้ผลลัพธ์จะเป็นทั้ง successful or failures response

ภาษา Python นั้นได้มี Library สำหรับการทำ unittest mock โดยสามารถทำการติดตั้งผ่าน Pip package manager ได้เลย 

$ pip install mock

 

การประกาศ Mock Object 

from unittest.mock import Mock
mock = Mock()
print(mock)>> <Mock id='140519256300896'>


การประกาศ Mock Object สำหรับ Mock Function

from unittest.mock import Mock 
mock = Mock() 
print(mock.get_coin_price()) >> <Mock name='mock.get_coin_price()' id='140379447928048'>


assert_called_once เป็นการตรวจสอบว่า mock object นั้นได้ถูกเรียก 1 ครั้ง

โดยจากโค้ดทำการ Mock Object ให้ทำการเรียกใช้ a_plus_b() โดยจะทำการตรวจสอบว่าฟังก์ชันนี้ได้ทำการเรียกใช้แล้ว 1 ครั้งหรือไม่

from unittest.mock import Mock
def a_plus_b(a,b):  return a+b
mock = Mock()
mock.a_plus_b()
mock.a_plus_b.assert_called_once()


หากทำการลบ mock.a_plus_b() ก็จะทำให้มันไม่ถูกเรียกใช้ และการทดสอบจะ fail

assert_called_with เป็นการตรวจสอบว่า Mock Object นั้นได้ถูกเรียกด้วยข้อมูลชุดนี้หรือไม่

โดยจากโค้ดทำการ Mock Object ขี้นมา mock.a_plus_b(a=20, b=25) โดยให้รับตัวแปร 2 ตัว จากนั้นบรรทัดถัดไปจึงมาทำการตรวจสอบว่าฟังก์ขั่นถูกเรียกด้วยข้อมูลที่เหมือนกันหรือไม่

from unittest.mock import Mock
def a_plus_b(a,b):  return a+b
mock = Mock()
mock.a_plus_b(a=20, b=25)
mock.a_plus_b.assert_called_with(a=20, b=25)


return_value ใช้ในการตั้งค่าข้อมูลที่จะถูกส่งกลับมาจาก Mock Object ของฟังก์ชัน โดยจากโค้ดจะทำการตั้งค่าให้ข้อมูลที่ถูกส่งกลับมาคือ 30

from unittest.mock import Mock
def a_plus_b(a,b):  return a+b
value = 30
mock = Mock()# ทำการ set ค่าให้ส่ง 30 กลับมาเมื่อเรียกใช้
mock_value = mock.a_plus_b().return_value = value
assert mock_value == value
print(mock.a_plus_b().return_value)>> 30


side_effect เป็นการ Mock Object ให้ฟังก์ชันที่โดน Mock นั้นเกิดผลลัพธ์ได้หลายแบบ เช่นจากโด้ดจะตั้งค่าให้หากเรียกใช้ครั้งแรกให้ใช้ค่าเลข 3 หากถูกเรียกครั้งถัดมาจะเป็น 2 ตามลำดับ และในฟังก์ชันสามารถรับค่าเป็น list หรือ ฟังก์ชันได้

from unittest.mock import Mock
mock = Mock()
mock.side_effect = [3, 2, 1]
print(mock(), mock(), mock())>> 3 2 1


call_count เป็นฟังก์ชันที่ใช้ในการนับจำนวนครั้งที่ฟังก์ชันที่ทำการ Mock Object ถูกเรียกใช้งาน

mock = Mock(return_value=None)
print(mock.call_count)>> 0
mock()
mock()
mock.call_count
print(mock.call_count)>> 2


ตัวอย่างการใช้ mock object ใน unittest

ถัดไปจะเป็นตัวอย่างการ Mock Object ทั้ง Request และ Response เนื่องจากต้องการทดสอบว่าหากทำการเรียกใช้ API ไป 2 ครั้ง โดยครั้งแรกจะควบคุมให้เมื่อเรียกใช้ API ให้บังคับให้เกิดเหตุการณ์ request timeout ส่วนครั้งที่ 2 สามารถเรียกใช้ ได้ปกติและได้ข้อมูลกลับมา

import unittest
from unittest.mock import Mock
from requests.exceptions import Timeout# Mock request
requests = Mock()
def get_bitcoin_price():  r = requests.get('http://localhost/api/crypto')  if r.status_code == 200:      return r.json()  return None
class TestCrypto(unittest.TestCase):  def test_crypto(self):              # Mock response      response_mock = Mock()      response_mock.status_code = 200      response_mock.json.return_value = {          'name': 'Bit Coin',          'price': 40000,          'rank': 1,      }              # Set side_effect สำหรับ .get method      requests.get.side_effect = [Timeout, response_mock]              # ทดสอบให้การเรียกใช้ครั้งแรกติด Timeout      with self.assertRaises(Timeout):              get_bitcoin_price()              # ทดสอบครั้งที่สองสำเร็จให้ตรวจสอบข้อมูล price มีค่าเท่ากีบ 40000      assert get_bitcoin_price()['price'] == 40000              # ทำการทดสอบ .get method ถูกเรียกใช้ไป 2 ครั้ง      assert requests.get.call_count == 2
if __name__ == '__main__':  unittest.main()

 


หล่งอ้างอิง

Unittest.mock — Mock object library, Python Development Tool.
Understanding the Python Mock Object Library, by Alex Ronquillo.

Written by
Senna Labs
Senna Labs

Subscribe to follow product news, latest in technology, solutions, and updates

- More than 120,000 people/day visit to read our blogs

Other articles for you

25
July, 2024
หน้ากากอนามัยสามารถปกป้องคุณจาก COVID-19 ได้จริงหรือ?
25 July, 2024
หน้ากากอนามัยสามารถปกป้องคุณจาก COVID-19 ได้จริงหรือ?
WHO ได้ออกมายืนยันว่าหน้ากากอนามัยธรรมดาเพียงอย่างเดียวไม่สามารถป้องกันคุณจากไวรัสโคโรน่าได้ ในขณะที่ผู้คนไม่สามารถครอบครองหน้ากากอนามัยได้มากเท่าจำนวนที่ต้องการเนื่องจากสาเหตุการแพร่ระบาดของ COVID-19 หรือ ไวรัสโคโรน่า ทำให้หน้ากากอนามัยขาดแคลนในหลายประเทศ แต่มีการยืนยันจากผู้เชี่ยวชาญว่าการใส่หน้ากากอนามัยเพียงอย่างเดียว ไม่สามารถช่วยป้องกันได้อย่างที่คาดไว้ Eric Toner นักวิทยาศาสตร์จากศูนย์สุขภาพของ Johns Hopkins กล่าวว่า "การใส่หน้ากากอนามัยเพียงอย่างเดียว ไม่สามารถช่วยป้องกันได้อย่างที่คาดไว้" รวมไปถึง ดร. William Schaffner ผู้เชี่ยวชาญด้านโรคติดเชื้อที่มหาวิทยาลัย Vanderbilt ในรัฐเทนเนสซียืนยันกับ Live Science ว่าหน้ากากอนามัยธรรมดาไม่สามารถป้องกันไวรัสโคโรนาได้ นอกจากนี้ ศูนย์ควบคุมและป้องกันโรคหรือ CDC ระบุว่า ทางป้องกันไวรัสโคโรนาที่ดีที่สุดคือการล้างมือบ่อย ๆ

By

1 mins read
Thai
25
July, 2024
Pace สตาร์ตอัปรายใหม่เปิดตัว Virtual Group Therapy
25 July, 2024
Pace สตาร์ตอัปรายใหม่เปิดตัว Virtual Group Therapy
จากสถิติ National Institutes of Health ของสหรัฐฯ บ่งชี้ว่าชาวอเมริกันจำนวน 1 ใน 5 ของคนประสบปัญหาด้านสุขภาพจิต (51.5 ล้านคนในปี 2019)บริษัทสตาร์ตอัปน้องใหม่อย่าง Pace ที่ก่อตั้งโดยผู้บริหารของ Pinterest และ Affirm จึงต้องการให้ความสำคัญกับเรื่องนี้ “ไม่มีใครที่จะมีสุขภาพจิตสมบูรณ์ดีตลอดเวลา”Jack Chou ผู้ร่วมก่อตั้ง Pace กล่าว เขาเชื่อว่าทุกคนจะอยู่ระหว่างการมีสุขภาพจิตแข็งแรงและไม่แข็งแรง ในขณะที่บางคนได้ผ่านการวินิฉัยภาวะสุขภาพจิต ซึ่งอาจได้รับการรักษาด้วยยา หรือการบำบัดรายเป็นบุคคล แต่ผู้ที่อยู่ในพื้นที่สีเทาที่ไม่อาจทราบได้ว่าตัวเองนั้นมีปัญหาหรือไม่ และอาจต้องการรักษาบางอย่างเพื่อให้สามารถดำเนินชีวิตต่อไปได้ ซึ่งหลังจากที่

By

3 mins read
Thai
25
July, 2024
Microsoft ได้ยื่นจดสิทธิบัตร ให้คนเกิดใหม่เป็น Chatbot ได้
25 July, 2024
Microsoft ได้ยื่นจดสิทธิบัตร ให้คนเกิดใหม่เป็น Chatbot ได้
จะดีไหม หากเราสามารถสื่อสารกับคนในครอบครัว คนรัก หรือแม้แต่เพื่อนของเราที่ได้จากไปจากโลกนี้แล้วได้ เพราะล่าสุด Microsoft ได้ยื่นจดสิทธิบัตร เพื่อเพิ่มความเป็นไปได้ในการให้คนที่เสียชีวิตไปแล้ว สามารถกลับมาเกิดใหม่เป็น Chatbot บนโลกดิจิทัลได้ ซึ่งในการสร้าง Chatbot นี้ แทนที่จะใช้วิธีการฝึกแบบเดิม ๆ โดยใช้การสนทนาและข้อมูลจากผู้ใช้กลุ่มตัวอย่าง ทาง Microsoft มีความคิดที่จะสร้าง Chatbot จากข้อมูลของบุคคลที่เสียชีวิต โดยระบบจะนำข้อมูลจาก Social media เช่น ข้อความ รูปภาพ ข้อมูลเสียง โพสต์ต่าง ๆ

By

3 mins read
Thai

Let’s build digital products that are
simply awesome !

We will get back to you within 24 hours!Go to contact us
Please tell us your ideas.
- Senna Labsmake it happy
Contact ball
Contact us bg 2
Contact us bg 4
Contact us bg 1
Ball leftBall rightBall leftBall right
Sennalabs gray logo28/11 Soi Ruamrudee, Lumphini, Pathumwan, Bangkok 10330+66 62 389 4599hello@sennalabs.com© 2022 Senna Labs Co., Ltd.All rights reserved.