การใช้วิธีการทั่วไป "any ()" ของ Mockito


194

ฉันมีอินเตอร์เฟซที่มีวิธีการที่คาดว่าอาร์เรย์ของFoo:

public interface IBar {
  void doStuff(Foo[] arr);
}

ฉันกำลังเยาะเย้ยอินเทอร์เฟซนี้โดยใช้ Mockito และฉันต้องการยืนยันที่doStuff()เรียกว่า แต่ฉันไม่ต้องการที่จะตรวจสอบข้อโต้แย้งที่ผ่าน - "ไม่สนใจ"

ฉันจะเขียนรหัสต่อไปนี้โดยใช้any()วิธีการทั่วไปได้anyObject()อย่างไร

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());

คำตอบ:


111

ตั้งแต่ Java 8 คุณสามารถใช้anyวิธีการที่ไม่มีข้อโต้แย้งและอาร์กิวเมนต์ประเภทจะได้รับการสรุปโดยคอมไพเลอร์:

verify(bar).doStuff(any());

คำอธิบาย

สิ่งใหม่ใน Java 8 คือประเภทเป้าหมายของนิพจน์จะถูกใช้เพื่ออนุมานพารามิเตอร์ประเภทของนิพจน์ย่อย ก่อนหน้า Java 8 จะแย้งกับวิธีที่ใช้สำหรับการอนุมานพารามิเตอร์ชนิด (ส่วนใหญ่)

ในกรณีนี้ประเภทพารามิเตอร์ของdoStuffจะเป็นประเภทเป้าหมายสำหรับany()และประเภทค่าตอบแทนของany()จะได้รับเลือกให้ตรงกับประเภทอาร์กิวเมนต์นั้น

กลไกนี้ถูกเพิ่มใน Java 8 เป็นหลักเพื่อให้สามารถรวบรวมแลมบ์ดานิพจน์ได้ แต่ส่วนใหญ่จะปรับปรุงการอนุมานประเภทโดยทั่วไป


ประเภทดั้งเดิม

วิธีนี้ใช้ไม่ได้กับประเภทดั้งเดิม แต่น่าเสียดายที่:

public interface IBar {
    void doPrimitiveStuff(int i);
}

verify(bar).doPrimitiveStuff(any()); // Compiles but throws NullPointerException
verify(bar).doPrimitiveStuff(anyInt()); // This is what you have to do instead

ปัญหาคือว่าคอมไพเลอร์จะสรุปเป็นค่าตอบแทนของInteger any()Mockito จะไม่ตระหนักถึงเรื่องนี้ (เนื่องจากการลบออกประเภท) nullและกลับค่าเริ่มต้นสำหรับประเภทการอ้างอิงซึ่งเป็น รันไทม์จะพยายามยกเลิกการส่งคืนค่าโดยเรียกintValueเมธอดนั้นก่อนส่งผ่านไปยังdoStuffและข้อยกเว้นจะถูกส่งออกไป


ฉันประหลาดใจทุกครั้งที่คำตอบนี้ได้รับ upvote! ฉันเดาว่าคำถามจะไม่ได้รับความสนใจมากนักตั้งแต่ Java 8 เนื่องจากanyวิธีการนี้ควรใช้งานได้ คุณไม่ต้องค้นหาคำตอบสำหรับสิ่งที่ใช้งานได้!
Lii

ฉันมาที่นี่เพราะฉันไม่รู้ว่าทำไมรหัสของฉันถึงใช้งานไม่ได้any()แต่ก็โอเคด้วยanyBoolean()ซึ่งส่วนสุดท้ายของคำตอบของคุณทำให้ไฟสว่างขึ้นอย่างสวยงาม
AdrienW

274

สิ่งนี้น่าจะใช้ได้

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

verify(bar).DoStuff(any(Foo[].class));

31
ในกรณีที่มีคนต้องการมันใน Scala:verify(bar).DoStuff(any[Array[Foo]])
tolitius

6
ฉันมีปัญหากับการนำเข้าฉันกำลังใช้ใด ๆ () จาก hamcrest ในการนำเข้าของฉันและมันชนกับของจาก mockito
Doppelganger

4
โปรดดูที่ API ซึ่งเป็นอากิวเมนต์คลาสที่ใช้สำหรับการแคสต์วิธียังคงรับวัตถุชนิดใดก็ได้! site.mockito.org/mockito/docs/current/org/mockito/... . ใช้ ISA () สำหรับกรณีนี้site.mockito.org/mockito/docs/current/org/mockito/...
thilko

1
คลาสนี้เลิกใช้แล้วเพื่อหลีกเลี่ยงการปะทะกันของชื่อกับ Hamcrest ใช้ org.mockito.ArgumentMatchers
leo9r

12

คุณสามารถใช้Mockito.isA()สำหรับ:

import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.verify;

verify(bar).doStuff(isA(Foo[].class));

http://site.mockito.org/mockito/docs/current/org/mockito/Matchers.html#isA(java.lang.Class)


นี่คือคำตอบที่ถูกต้อง การใช้ (Clazz) ผิดทั้งหมด
Surasin Tancharoen

3
@SurasinTancharoen ที่จริงแล้ว (Class) ใด ๆ เป็นเพียงนามแฝงของ isA (Class) (ดูเอกสาร) ดังนั้นจึงไม่ผิดเลย
jmiserez

8

ตามที่ฉันต้องการใช้คุณลักษณะนี้สำหรับโครงการล่าสุดของฉัน (ณ จุดหนึ่งเราอัปเดตจาก 1.10.19) เพียงเพื่อให้ผู้ใช้ (ที่ใช้mockito-core version 2.1.0 หรือสูงกว่า ) อยู่เสมอแบบคงที่ ควรใช้วิธีการจากคำตอบข้างต้นArgumentMatchersชั้นเรียน:

import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;

โปรดระลึกไว้เสมอว่าหากคุณวางแผนที่จะทำให้สิ่งประดิษฐ์ Mockito ของคุณทันสมัยอยู่เสมออาจเริ่มจากรุ่น 3 คลาสนี้อาจไม่มีอยู่อีกต่อไป:

ตั้งแต่ 2.1.0 ขึ้นไป Javadoc of org.mockito.Matchers กล่าวว่า:

org.mockito.ArgumentMatchersใช้ คลาสนี้เลิกใช้แล้วเพื่อหลีกเลี่ยงการปะทะกันของชื่อกับ Hamcrest *org.hamcrest.Matchers ระดับ คลาสนี้จะถูกลบในเวอร์ชัน 3.0

ฉันได้เขียนบทความเล็กน้อยเกี่ยวกับสัญลักษณ์ตัวแทน mockitoหากคุณพร้อมสำหรับการอ่านเพิ่มเติม


ฉันจะนำเข้า org.mockito.ArgumentMatcher ใน Scala ได้อย่างไร ฉันพยายามนำเข้า org.mockito.ArgumentMatcher.any ฉันได้รับข้อผิดพลาด `ค่าใด ๆ ไม่ได้เป็นสมาชิกของวัตถุ org.mockito.ArgumentMatcher
Manu Chadha

คุณช่วยบอกฉันหน่อยได้ไหมว่าอะไรคือสิ่งที่เทียบเท่าในรุ่น 3.0?
มนู Chadha

เราจะรู้ได้ทันทีว่ามันจะถูกปล่อยออกมา;)
Maciej Kowalski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.