PowerMockito จำลองวิธีการคงที่เดียวและส่งคืนวัตถุ


100

ฉันต้องการจำลองวิธีการคงที่ m1 จากคลาสซึ่งมี 2 วิธีแบบคงที่คือ m1 และ m2 และฉันต้องการให้เมธอด m1 ส่งคืนวัตถุ

ฉันลองทำดังต่อไปนี้

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable {
            return 1000l;
         }
      });

นี่คือการเรียกทั้ง m1 และ m2 ซึ่งมีประเภทการส่งคืนที่แตกต่างกันดังนั้นจึงมีข้อผิดพลาดที่ไม่ตรงกัน

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); แต่จะไม่ถูกเรียกเมื่อเรียกใช้ m1

3) PowerMockito.mockPartial(Static.class, "m1"); ให้รวบรวมข้อผิดพลาดที่ไม่สามารถใช้ได้ mockPartial ซึ่งผมได้จากhttp://code.google.com/p/powermock/wiki/MockitoUsage

คำตอบ:


136

สิ่งที่คุณต้องการทำคือการรวมกันของส่วนที่ 1 และทั้งหมดของ 2

คุณต้องใช้ PowerMockito.mockStatic เพื่อเปิดใช้งานการจำลองแบบคงที่สำหรับวิธีการแบบคงที่ทั้งหมดของคลาส ซึ่งหมายความว่าทำให้สามารถขีดฆ่าโดยใช้ไวยากรณ์ when-thenReturn

แต่การโอเวอร์โหลด 2 อาร์กิวเมนต์ของ mockStatic ที่คุณใช้เป็นกลยุทธ์เริ่มต้นสำหรับสิ่งที่ Mockito / PowerMock ควรทำเมื่อคุณเรียกใช้เมธอดที่คุณไม่ได้ถูกตรึงไว้อย่างชัดเจนบนอินสแตนซ์จำลอง

จากjavadoc :

สร้างคลาสจำลองด้วยกลยุทธ์ที่ระบุสำหรับคำตอบของการโต้ตอบ เป็นคุณสมบัติขั้นสูงและโดยทั่วไปคุณไม่จำเป็นต้องเขียนแบบทดสอบที่ดี อย่างไรก็ตามจะมีประโยชน์เมื่อทำงานกับระบบเดิม เป็นคำตอบเริ่มต้นดังนั้นจะใช้เฉพาะเมื่อคุณไม่ทำให้การเรียกเมธอดสะดุด

กลยุทธ์การตัดค่าเริ่มต้นที่เป็นค่าเริ่มต้นคือเพียงส่งคืนค่า null, 0 หรือ false สำหรับอ็อบเจ็กต์ตัวเลขและเมธอดที่มีมูลค่าบูลีน โดยใช้ 2-arg overload คุณจะพูดว่า "No, no, no, โดยค่าเริ่มต้นให้ใช้วิธีการตอบของ Answer subclass 'เพื่อรับค่าเริ่มต้นซึ่งจะส่งกลับค่า Long ดังนั้นหากคุณมีวิธีการคงที่ซึ่งส่งคืนสิ่งที่ไม่เข้ากัน นานมีปัญหา

ให้ใช้ mockStatic เวอร์ชัน 1-arg เพื่อเปิดใช้งานวิธีการแบบคงที่จากนั้นใช้ when-thenReturn เพื่อระบุสิ่งที่ต้องทำสำหรับเมธอดเฉพาะ ตัวอย่างเช่น:

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics {
  public static String getString() {
    return "String";
  }

  public static int getInt() {
    return 1;
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
  @Test
  public void test() {
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  }
}

วิธีการคงที่ที่มีค่าสตริงถูกตัดออกเพื่อส่งคืน "Hello!" ในขณะที่วิธีการคงที่ที่มีค่า int ใช้ค่าเริ่มต้นของการดึงค่าเริ่มต้นกลับเป็น 0


1
ไม่จำเป็นต้องเล่นซ้ำหรือไม่?
Balaji Boggaram Ramanarayan

อืม ... sorta น่าจะเป็นเช่นนั้น บางที PowerMockito จะเล่น PowerMock ซ้ำให้คุณหรือไม่? ฉันยังสงสัยเกี่ยวกับเรื่องนั้น
djangofan

3
แต่จะเกิดอะไรขึ้นถ้าฉันต้องการให้แน่ใจว่าวิธีการแบบคงที่ถูกเรียกด้วยอาร์กิวเมนต์ที่แม่นยำ?
elTomato

6
@PrepareForTestคำอธิบายประกอบควรจะเป็นระดับที่เรียกว่าวิธีการแบบคงที่ไม่ได้ระดับที่วิธีการคงเป็น
Hazel Troost

6
@HazelTroost - ไม่ OP ถูกต้อง เป็นคลาสที่มีวิธีการคงที่ที่ควรเตรียมสำหรับการทดสอบ ดังนั้น@PrepareForTest(ClassWithStatics.class)ที่ถูกต้อง
arry36
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.