วิธีการตรวจสอบว่าวิธีนั้นไม่ได้ถูกเรียกใน Moq?


466

ฉันจะตรวจสอบวิธีการที่ไม่ได้เรียกว่าในMoq ได้อย่างไร?

มันมีบางอย่างเช่น AssertWasNotCalled หรือไม่?

อัปเดต: เริ่มจากเวอร์ชัน 3.0 คุณสามารถใช้ไวยากรณ์ใหม่ได้:

mock.Verify(foo => foo.Execute("ping"), Times.Never());

คำตอบ:


155

อัปเดต : ตั้งแต่เวอร์ชัน 3 ให้ตรวจสอบการอัปเดตของคำถามด้านบนหรือคำตอบของ Dann ด้านล่าง

ทำแบบจำลองให้เข้มงวดดังนั้นมันจะล้มเหลวถ้าคุณเรียกใช้วิธีการที่คุณไม่คาดคิด

new Mock<IMoq>(MockBehavior.Strict)

หรือถ้าคุณต้องการจำลองของคุณจะหลวมใช้. Throws (ข้อยกเว้น)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));

9
... หรือ Callback () เพื่อตั้งค่าสถานะบางอย่างที่สามารถยืนยันได้
alex

2
นอกจากนี้ยังมีตัวเลือก # 2 คุณไม่สามารถมี VerifyAll ในวิธีการ Teardown ทั่วไป - จะไม่สามารถบอกได้ว่าไม่เป็นไปตามความคาดหวัง เมื่อการทดสอบควรผ่าน
Gishu

51
นี่ไม่ใช่ "การยืนยันที่ไม่ได้เรียกว่า" เพราะมันสามารถถูกตรวจจับได้ภายในวิธีการและยังคงใช้งานได้ - ให้ผลบวกที่ผิด!
ด่าน

4
คาดว่าจะเลิกในขณะนี้
Tomasz Sikora

5
นี่อาจเป็นวิธีที่ดีที่สุดในปี 2009 แต่ไม่ใช่ตอนนี้ ขอโทษ
Fabio Milheiro

537

เรียกใช้การตรวจสอบหลังจากการทดสอบที่มีการTimes.Neverกำหนด Enum เช่น

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());

4
สิ่งสำคัญที่นี่คือการเรียกใช้ Verify (action, Never) หลังจากการเรียกไปยัง mock ฉันคิดว่ามันตั้งค่าการตรวจสอบสำหรับการโทร VerifyAll () ในภายหลัง (ซึ่งใช้งานไม่ได้ )
piers7

ง่ายและมีประสิทธิภาพ ขอบคุณ
Ian Grainger

45

ขโมยมาจาก: John Foster ตอบคำถามนี้ว่า "ต้องการความช่วยเหลือในการทำความเข้าใจ Moq ให้ดีขึ้น"

สิ่งหนึ่งที่คุณอาจต้องการทดสอบคือวิธีการจ่ายเงินจะไม่ถูกเรียกเมื่อบุคคลที่มีอายุมากกว่า 65 ปีถูกส่งเข้าสู่วิธีการนั้น

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}

10

สิ่งนี้ไม่ทำงานใน Moq รุ่นล่าสุด (ตั้งแต่อย่างน้อย 3.1) ควรระบุในVerifyวิธีการตามที่ระบุไว้ในคำตอบ

จริงๆแล้วมันเป็นการดีกว่าที่จะระบุ.AtMost(0)หลังคำสั่ง Return

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);

แม้ว่า "พ่น" ก็ใช้งานได้ แต่AtMost(0)IMHO ก็แสดงออกได้มากกว่า


-5

ใช้. AtMostOnce ();

หลังจากการทดสอบจริงเรียกวิธีการอีกครั้ง หากมีข้อผิดพลาดจะถูกเรียก


1
ไม่คลุมเครือเล็กน้อยใช่ไหมที่จะยืนยันว่าข้อยกเว้นนั้นถูกโยนทิ้งโดยการเยาะเย้ยกรอบงาน
alex

ทำไม? เพียงตรวจสอบประเภทของข้อยกเว้น ถ้ามันเป็นหนึ่งโยนขั้นต่ำของฉันคุณจะปลอดภัย
Aaron Digulla

8
ใช้ Verify with Times.Never เป็นตัวเลือกที่ดีกว่า ... ฉันเห็นด้วยกับ alex ว่าโซลูชันนี้ใช้งานได้ แต่ไม่ชัดเจน
ปี๊บปี๊บ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.