Stubbing Properties พร้อมเซ็ตส่วนตัวสำหรับการทดสอบ


10

เรามีวัตถุ

public class MyObject{
    protected MyObject(){}

    public string Property1 {get;private set;}
    public string Property2 {get;private set;}
    public string Property3 {get;private set;}
    public string Property4 {get;private set;}
    public string Property5 {get;private set;}
    public string Property6 {get;private set;}
    public string Property7 {get;private set;}
    public string Property8 {get;private set;}
    public string Property9 {get;private set;}
    public string Property10 {get;private set;}
}

ในรหัสการผลิตของเราเราเติมวัตถุนี้ผ่าน automapper สามารถเข้าถึงคุณสมบัติและตั้งค่าได้อย่างถูกต้อง

ตอนนี้เมื่อเราต้องการทดสอบคลาสนี้ในไปป์ไลน์ในอนาคตมันเป็นไปไม่ได้ที่จะเติมคุณสมบัติที่มีค่าตัวอย่าง (ที่จะทดสอบ)

มีตัวเลือกน้อยใช้ได้

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

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

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

ข้อเสนอแนะคำแนะนำหรือตัวเลือกอื่น ๆ ที่นี่?

คำตอบ:


8

คุณมีตัวเลือกมากมาย

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

  • รวม automapper ในกระบวนการทดสอบ บางคนจะบอกว่านี่ไม่ใช่การทดสอบหน่วยอีกต่อไป ไม่เป็นไร. การทดสอบหน่วยไม่ใช่การทดสอบชนิดเดียว

  • ใช้สิ่งที่มีฟังก์ชันการทำงานของ automapper โดยเฉพาะสำหรับการทดสอบ คุณสามารถเขียนยูทิลิตี้เล็ก ๆ น้อย ๆ ซึ่งจะใช้การสะท้อนเพื่อเติมวัตถุของคุณจากพจนานุกรมที่มีชื่อคุณสมบัติและค่า

โปรดดูคำถามและคำตอบนี้ด้วย: คุณอยากทำแบบทดสอบส่วนตัวภายใน / สาธารณะเพื่อทดสอบหรือใช้แฮ็คอย่าง PrivateObject บ้างไหม?


3

ฉันไม่ลังเลที่จะใช้การไตร่ตรองสำหรับสิ่งต่างๆเช่นนี้ในการทดสอบ

ฉันไม่ชอบที่จะทำสิ่งต่างๆเสมือนจริงเพื่อเยาะเย้ยเพราะเปลี่ยนรหัสด้วยเหตุผลที่ผิด

ฉันไม่รู้จัก automapper แต่ฉันเห็นด้วยกับ @Mike ว่าการรวมไว้ในการทดสอบอาจเป็นความคิดที่ดี การทดสอบหน่วยแตกต่าง / การรวมเข้าด้วยกันไม่ได้เป็น IMO ที่น่าสนใจมาก แน่นอนว่าถ้าชุดทดสอบมีขนาดใหญ่และช้าคุณจะต้องกรองและจัดประเภทสิ่งต่าง ๆ เพื่อให้ทำงานได้เพียงชุดย่อยที่เหมาะสมของการทดสอบทั้งหมดที่ความถี่สูงสุด

ตัวอย่างการแฮ็กโดยใช้การสะท้อนการใช้ nameof () จะมีความสมบูรณ์แบบที่ดีกว่า แต่คุณจะเสียประเภท:

public static class TestExtensions
{
    public static void SetProperty<TSource, TProperty>(
        this TSource source,
        Expression<Func<TSource, TProperty>> prop,
        TProperty value)
    {
        var propertyInfo = (PropertyInfo)((MemberExpression)prop.Body).Member;
        propertyInfo.SetValue(source, value);
    }
}

0

สำหรับวัตถุประสงค์ในการทดสอบหน่วยใช้ประโยชน์จากกรอบการเยาะเย้ยเช่น Microsoft Fakes, TypeMock และ JustMock ซึ่งให้การสนับสนุนสำหรับการเยาะเย้ยสมาชิกส่วนตัว

โปรดดูที่ Smocks (แพ็คเกจ avaiable @nuget) ด้วย ข้อ จำกัด ของเสื้อคลุมคือมันจะไม่ให้การเข้าถึงสมาชิกส่วนตัว แต่ก็มีความสามารถในการเยาะเย้ยสมาชิกคงที่และไม่เสมือน นอกจากนี้ยังมีให้บริการฟรี

อีกวิธีที่ง่ายที่สุดคือการใช้ PrivateObject / PrivateType

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