เราทำการทดสอบหน่วยของเราทั้งหมดในโครงการของตนเอง เราพบว่าเราต้องทำให้บางคลาสเป็นแบบสาธารณะแทนที่จะเป็นแบบภายในเพื่อการทดสอบหน่วย มีอยู่แล้วเพื่อหลีกเลี่ยงการทำเช่นนี้ อะไรคือความหมายของความทรงจำโดยการทำให้ชั้นเรียนเป็นแบบสาธารณะแทนที่จะถูกผนึก?
เราทำการทดสอบหน่วยของเราทั้งหมดในโครงการของตนเอง เราพบว่าเราต้องทำให้บางคลาสเป็นแบบสาธารณะแทนที่จะเป็นแบบภายในเพื่อการทดสอบหน่วย มีอยู่แล้วเพื่อหลีกเลี่ยงการทำเช่นนี้ อะไรคือความหมายของความทรงจำโดยการทำให้ชั้นเรียนเป็นแบบสาธารณะแทนที่จะถูกผนึก?
คำตอบ:
หากคุณใช้. NET แอตทริบิวต์แอสเซมบลีInternalsVisibleToช่วยให้คุณสร้างแอสเซมบลี "เพื่อน" แอสเซมบลีเหล่านี้มีชื่อเฉพาะอย่างยิ่งที่ได้รับอนุญาตให้เข้าถึงคลาสภายในและสมาชิกของแอสเซมบลีอื่น
หมายเหตุควรใช้สิ่งนี้ด้วยดุลยพินิจเนื่องจากเป็นคู่ประกอบที่เกี่ยวข้อง การใช้งานทั่วไปสำหรับ InternalsVisibleTo สำหรับโครงการทดสอบหน่วย อาจไม่ใช่ทางเลือกที่ดีสำหรับการใช้งานในแอปพลิเคชันแอสเซมบลีที่แท้จริงของคุณด้วยเหตุผลที่กล่าวข้างต้น
ตัวอย่าง:
[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
หากเป็นคลาสภายในจะต้องไม่ใช้งานแบบแยก ดังนั้นคุณไม่ควรทำการทดสอบนอกเหนือจากการทดสอบคลาสอื่นที่ใช้ประโยชน์จากวัตถุนั้นภายใน
เช่นเดียวกับที่คุณไม่ควรทดสอบสมาชิกส่วนตัวของคลาสคุณไม่ควรทดสอบคลาสภายในของ DLL ชั้นเรียนเหล่านี้เป็นรายละเอียดการนำไปปฏิบัติของชั้นเรียนที่สาธารณชนสามารถเข้าถึงได้ดังนั้นจึงควรออกกำลังกายอย่างดีผ่านการทดสอบหน่วยอื่น ๆ
แนวคิดก็คือคุณต้องการทดสอบพฤติกรรมของชั้นเรียนเท่านั้นเพราะถ้าคุณทดสอบรายละเอียดการใช้งานภายในการทดสอบของคุณจะเปราะบาง คุณควรจะสามารถเปลี่ยนรายละเอียดการใช้งานของคลาสใดก็ได้โดยไม่ต้องทำการทดสอบทั้งหมด
หากคุณพบว่าคุณต้องการทดสอบคลาสนั้นจริง ๆ คุณอาจต้องการตรวจสอบอีกครั้งว่าทำไมคลาสนั้นถึงอยู่ภายในในตอนแรก
เพื่อวัตถุประสงค์ด้านเอกสาร
หรือคุณสามารถสร้างอินสแตนซ์ของคลาสภายในโดยใช้Type.GetType
วิธีการ
ตัวอย่าง
//IServiceWrapper is public class which is
//the same assembly with the internal class
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
.CreateInstance(type, new object[1] { /*constructor parameter*/ });
สำหรับประเภททั่วไปมีกระบวนการที่แตกต่างกันเป็นร้อง:
var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
.CreateInstance(genType, new object[1] { /*constructor parameter*/});
ชั้นเรียนสามารถเป็นได้ทั้งสาธารณะและปิดผนึก
แต่อย่าทำอย่างนั้น
คุณสามารถสร้างเครื่องมือเพื่อสะท้อนชั้นเรียนภายในและปล่อยคลาสใหม่ที่เข้าถึงทุกสิ่งผ่านการสะท้อนกลับ MSTest ทำเช่นนั้น
แก้ไข: ฉันหมายถึงถ้าคุณไม่ต้องการรวมสิ่ง - การทดสอบ - ในแอสเซมบลีดั้งเดิมของคุณ วิธีนี้จะใช้งานได้หากสมาชิกเป็นแบบส่วนตัว
public sealed class
อะไร เหตุผลของคุณสำหรับอัญมณีนั้นคืออะไร?