การพัฒนา unit test โดย shim type

Shims เป็นหนึ่งใน technology ที่อยู่ใน Microsoft Fakes Framework ใช้ในการพัฒนา unit testing เพื่อแยก component ที่ต้องการทดสอบออกมาจากปัจจัยแวดล้อมต่างรอบๆ component ในกระบวนการทดสอบ โดย shims จะทำการเปลี่ยนทิศทางการเรียกใช้ method ที่กำหนด ไปยัง code ที่เขียนขึ้นมาใช้ในการทดสอบ ส่วนใหญ่เราจะใช้ shims เพื่อแยก component ที่ต้องการทดสอบออกจาก assemblies ที่ไม่ได้เป็นส่วนหนึ่งของ solution ในการพัฒนา (กรณีที่ต้องการแยก component ที่ต้องการทดสอบออกจาก solution ของตัวเอง ควรจะใช้ stubs )

method ที่พัฒนาส่วนใหญ่จะ return ผลการทำงานที่ต้องขึ้นกับเงื่อนไข ปัจจัยต่างๆจากภายนอก ในทางกลับกันสำหรับ shim  shim จะอยู่ภายใต้การควบคุมในกระบวนการทดสอบ สามารถที่จะ return ผลการทำงานตามที่กำหนดในทุกๆครั้งที่เรียกใช้งาน ซึ่งทำให้การเขียน unit testing ทำได้ง่ายขึ้นมาก

ตัวอย่าง method การตรวจสอบวันที่เอกสารในปีงบประมาณ

public static class Utility {
    public static bool IsInFiscalYear() {
        if (DateTime.Now < new DateTime(2015, 10, 1))
            return false;
        else
            return true;
    }
}

เมื่อต้องการทดสอบ method “IsInFiscalYear” จะพบว่าการทำงานของ method ขึ้นอยู่กับ DateTime.Now ซึ่งเป็นเวลาปัจุจบันที่ได้จากระบบ ซึ่งทำให้การทดสอบยุ่งยากขึ้น (เมื่อทำการทดสอบต้องเปลี่ยน DateTime เพื่อทำการทดสอบ ซึ่งอาจจะกระทบกับส่วนอื่นๆ ไม่สามารถทำการทดสอบแบบอัตโนมัติได้ ) ซึ่งการทดสอบ method ที่มีการเรียกใช้ database, web service ก็เช่นเดียวกัน เนื่องจากกลไกการทำงานขึ้นอยู่กับปัจจัยภายนอก ซึ่ง shim จะเข้ามาช่วยตรงจุดนี้

Shim types จะให้กลไกการเปลี่ยนทิศทางการเรียกใช้ .NET method ไปยัง function ( หรือ user delegate) ที่เขียนขึ้น โดย shim types จะถูกสร้างโดย Fakes generator

using (ShimsContext.Create()
{
    ShimDateTime.NowGet = () => new DateTime(2016, 6, 1);
    var isIn = Utility.IsInFiscalYear();

    Assert.AreEqual(true, isIn);
}

ShimDateTime คือ shim type ที่ถูกสร้างโดย Fakes generator เพื่อใช้ในการกำหนดกลไกการทำงานแทน DateTime.Now

การเพิ่ม Fakes Assemblies ใน solution ทำได้โดย

  1. ใน solution explorer ขยาย References ของ unit test project
  2. เลือก assembly ที่มี class ที่ต้องการสร้าง shim type (จากตัวอย่างนี้ต้องการสร้าง shim type ของ DateTime ให้เลือก System.dll)
  3. click ขวา เลือก Add Fakes Assembly

ในการใช้ shim type ใน unit test framework จะต้องเขียน test code อยู่ใน ShimsContext เพื่อควบคุม lifetime ของ shim type (ถ้าไม่อยู่ภายใต้ ShimsContext, shim type จะคงอยู่จนกระทั่งปิดโปรแกรม) การสร้าง ShimsContext ทำได้โดยการเรียกใช้งาน static Create() ดังเช่นตัวอย่าง code ข้างต้น

shim type สามารถใช้งานแทนที่ .NET method รวมทั้ง static method, instance method

Static methods

ShimMyClass.MyStaticMethod = () =>5;

Instance methods สำหรับทุก instance

ShimMyClass.AllInstances.MyMethod = () => 5;

Instance methods แต่ละ instance

var myClass1 = new ShimMyClass()
{
    MyMethod = () => 5
};

 

อ้างอิง :

  • https://msdn.microsoft.com/en-us/library/hh549176.aspx