MockK: ספרייה לועגת לקוטלין

1. סקירה כללית

במדריך זה, אנו נסתכל על כמה מהתכונות הבסיסיות של ספריית MockK.

2. MockK

בקוטלין כל השיעורים והשיטות הם סופיים. אמנם זה עוזר לנו לכתוב קוד שאינו משתנה, אך הוא גם גורם לבעיות במהלך הבדיקה.

ברוב ספריות ה MVM של JVM יש בעיות ללעוג או לדקור שיעורי גמר. כמובן שנוכל להוסיף את "לִפְתוֹחַמילת מפתח לשיעורים ולשיטות שאנחנו רוצים ללעוג להם. אבל שינוי כיתות רק ללעוג לקוד כלשהו לא מרגיש כמו הגישה הטובה ביותר.

כאן מגיעה ספריית MockK, המציעה תמיכה בתכונות ובנייה של שפות Kotlin. MockK בונה proxies עבור שיעורים לעגים. זה גורם לירידה מסוימת בביצועים, אך היתרונות הכלליים ש- MockK נותנת לנו שווים את זה.

3. התקנה

ההתקנה פשוטה ככל שהיא יכולה להיות. אנחנו רק צריכים להוסיף את התלות mockk לפרויקט Maven שלנו:

 מבחן io.mockk mockk 1.9.3 

עבור Gradle, עלינו להוסיף אותו כתלות בבדיקה:

testImplementation "io.mockk: mockk: 1.9.3"

4. דוגמה בסיסית

בואו ניצור שירות שאנחנו רוצים ללעוג לו:

class TestableService {fun getDataFromDb (testParameter: String): String {// database database and return matching value} fun doSomethingElse (testParameter: String): String {return "אני לא רוצה!" }}

הנה מבחן לדוגמא שלעג TestableService:

@Test fun givenServiceMock_whenCallingMockedMethod_thenCorrectlyVerified () {// given val service = mockk () every {service.getDataFromDb ("Parameter Expected")} מחזיר "פלט צפוי" // כאשר val result = service.getDataFromDb ("פרמטר צפוי") // ואז אמת את {service.getDataFromDb ("פרמטר צפוי")} assertEquals ("פלט צפוי", תוצאה)}

כדי להגדיר את האובייקט המדומה, השתמשנו ב- mockk () שיטה.

בשלב הבא הגדרנו את התנהגות הלעג שלנו. למטרה זו, יצרנו כֹּל חסום המתאר איזו תגובה יש להחזיר עבור איזו שיחה.

לבסוף, השתמשנו ב- תאשר לחסום כדי לוודא אם הלעג הופעל כפי שציפינו.

5. דוגמה להערות

אפשר להשתמש בהערות MockK כדי ליצור כל סוג של לעג. בואו ניצור שירות הדורש שני מקרים משלנו TestableService:

class InjectTestService {lateinit var service1: TestableService lateinit var service2: TestableService fun invokeService1 (): String {return service1.getDataFromDb ("Test Param")}}

InjectTestService מכיל שני שדות מאותו סוג. זו לא תהיה בעיה עבור MockK. MockK מנסה להתאים מאפיינים לפי שם, ואז לפי מחלקה או מעמד על. זה גם אין שום בעיה עם הזרקת חפצים לשדות פרטיים.

בואו ללעוג InjectTestService במבחן באמצעות הערות:

Class AnnotationMockKUnitTest {@MockK lateinit var service1: TestableService @MockK lateinit var service2: TestableService @InjectMockKs var objectUnderTest = InjectTestService () @BeforeEach fun setUp () = MockKAnnotations.init (this) // Tests here ...}

בדוגמה שלעיל השתמשנו ב- @InjectMockKs ביאור. זה מציין אובייקט שבו יש להזריק לעגים מוגדרים. כברירת מחדל, הוא מזריק משתנים שעדיין לא הוקצו. אנחנו יכולים להשתמש @OverrideMockKs כדי לבטל שדות שיש להם ערך כבר.

MockK דורש MockKAnnotations.init (...) להיקרא על אובייקט שמכריז על משתנה עם ביאורים. עבור Junit5, ניתן להחליף אותו עם @ExtendWith (MockKExtension :: class).

6. מרגל

מרגל מאפשר ללעוג רק לחלק מסוים בכיתה כלשהי. לדוגמה, ניתן להשתמש בו ללעוג לשיטה ספציפית ב- שירות לבדיקה:

@Test fun givenServiceSpy_whenMockingOnlyOneMethod_thenOtherMethodsShouldBehaveAsOriginalObject () {// given val service = spyk () כל {service.getDataFromDb (any ())} מחזיר "פלט מעוקל" // בעת בדיקת שיטה הלעוגה val firstResultrom = service.getata // ואז assertEquals ("פלט ללעג", firstResult) // כאשר בודקים שיטה לא לגלגל val secondResult = service.doSomethingElse ("כל פרמטר") // ואז assertEquals ("אני לא רוצה!", secondResult)}

בדוגמה השתמשנו ב- spyk שיטה ליצירת אובייקט ריגול. יכולנו להשתמש גם ב @SpyK ביאור כדי להשיג את אותו הדבר:

class SpyKUnitTest {@SpyK lateinit var service: TestableService // Tests here}

7. מוק רגוע

חפץ לעג אופייני יזרוק MockKException אם ננסה לקרוא לשיטה שבה ערך ההחזר לא צוין.

אם איננו רוצים לתאר את ההתנהגות של כל שיטה, נוכל להשתמש בלעג נינוח. סוג מדומה זה מספק ערכי ברירת מחדל עבור כל פונקציה. לדוגמא, ה חוּט סוג החזרה יחזיר ריק חוּט. הנה דוגמה קצרה:

@Test fun givenRelaxedMock_whenCallingNotMockedMethod_thenReturnDefaultValue () {// given val service = mockk (relaxed = true) // when val result = service.getDataFromDb ("כל פרמטר") // ואז assertEquals ("", תוצאה)}

בדוגמה השתמשנו ב- מוק שיטה עם רָגוּעַ תכונה ליצור אובייקט מדומה רגוע. יכולנו להשתמש גם ב @ RelaxedMockK ביאור:

class RelaxedMockKUnitTest {@RelaxedMockK lateinit var service: TestableService // Tests here}

8. אובייקט מדומה

Kotlin מספק דרך קלה להכריז על יחיד באמצעות ה- לְהִתְנַגֵד מילת מפתח:

אובייקט TestableService {כיף getDataFromDb (testParameter: מחרוזת): מחרוזת {// מאגר שאילתות והחזרת ערך התאמה}}

עם זאת, ברוב הספריות הלועגות יש בעיה ללעוג למופעים יחידים של קוטלין. בגלל זה, MockK מספקת את mockkObject שיטה. בואו נסתכל:

@Test כיף givenObject_whenMockingIt_thenMockedMethodShouldReturnProperValue () {// נתון mockkObject (TestableService) // בעת קריאה לא שיטה ללעג Val firstResult = service.getDataFromDb ("כל פרמטר") // ואז להחזיר assertEquals תגובה אמיתית (/ * תוצאה DB) // בעת קריאה לשיטה הלעגית כל {service.getDataFromDb (any ())} מחזיר "פלט ללעג" val secondResult = service.getDataFromDb ("כל פרמטר") // ואז מחזיר assertEquals תגובה ללעג ("פלט נלעג", secondResult)}

9. לגלוג היררכי

תכונה שימושית נוספת של MockK היא היכולת ללעוג לאובייקטים היררכיים. ראשית, בואו ניצור מבנה אובייקטים היררכי:

מחלקה Foo {שם lateinit var: מחרוזת lateinit var bar: Bar} Bar class (כותרת lateinit var: String)

ה פו מחלקה מכילה שדה מסוג בָּר. כעת אנו יכולים ללעוג למבנה בצעד קל אחד בלבד. בואו ללעוג ל שֵׁם ו כינוי שדות:

@Test fun givenHierarchicalClass_whenMockingIt_thenReturnProperValue () {// given val foo = mockk {every {name} מחזירה "Karol" כל {bar} מחזירה mockk {כל {nickname} מחזירה "Tomato"}} // כאשר val name = foo.name val כינוי = foo.bar.nickname // ואז assertEquals ("Karol", שם) assertEquals ("Tomato", כינוי)}

10. לכידת פרמטרים

אם נצטרך ללכוד את הפרמטרים שהועברו לשיטה, נוכל להשתמש בהם לכידת מגרש אוֹ MutableList. זה שימושי כשאנחנו רוצים שיהיה לנו היגיון מותאם אישית ב- תשובה לחסום או שאנחנו רק צריכים לאמת את ערך הטיעונים שהועברו. הנה דוגמה ל לכידת מגרש:

@Test fun givenMock_whenCapturingParamValue_thenProperValueShouldBeCaptured () {// given val service = mockk () val slot = slot () כל {service.getDataFromDb (לכידה (חריץ))} מחזירה "פלט צפוי" // כאשר service.getDataFromDb ("פרמנט צפוי" ) // ואז assertEquals ("צפוי פרמטר", slot.captured)}

MutableList ניתן להשתמש בכדי ללכוד ולאחסן ערכי ארגומנטים ספציפיים לכל קריאות השיטה:

@Test fun givenMock_whenCapturingParamsValues_thenProperValuesShouldBeCaptured () {// given val service = mockk () val list = mutableListOf () כל {service.getDataFromDb (לכידה (רשימה))} מחזירה "פלט צפוי" // כאשר service.getDataFromDb (" ") service.getDataFromDb (" פרמטר 2 צפוי ") // ואז assertEquals (2, list.size) assertEquals (" פרמיית 1 צפויה ", רשימה [0]) assertEquals (" פרמטר 2 צפוי, רשימה [1])}

11. מסקנה

במאמר זה דנו בתכונות החשובות ביותר של MockK. MockK היא ספרייה עוצמתית לשפת קוטלין ומספקת הרבה תכונות שימושיות. למידע נוסף על MockK, אנו יכולים לבדוק את התיעוד באתר MockK.

כמו תמיד, קוד הדוגמה שהוצג זמין שוב ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found