0Pricing
C# Academy · บทเรียน

ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ

ฉีดการพึ่งพาผ่านอินเทอร์เฟซ เขียนตัวจำลองอย่างง่ายเพื่อสังเกตพฤติกรรม และสร้างข้อมูลเข้าที่ซับซ้อนด้วยตัวสร้างข้อมูลทดสอบขนาดเล็ก

ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน

การแยกส่วนด้วยตัวจำลอง

เป้าหมาย: แยกโค้ดที่อยู่ระหว่างการทดสอบออกจากส่วนอื่น

  • พึ่งพาอินเทอร์เฟซ
  • จัดเตรียมตัวจำลองในการทดสอบ
  • ใช้ตัวสร้างขนาดเล็กสำหรับข้อมูลนำเข้าที่ซับซ้อน
  • สังเกตการเรียกใช้งาน ไม่ใช่โลกจริง

ฉีดเวลาเข้าผ่าน IClock

ซ่อนเวลาไว้เบื้องหลัง IClock การทดสอบจะส่งนาฬิกาจำลองเพื่อให้ได้ผลลัพธ์ที่คาดเดาได้

using System;

public interface IClock { DateTime NowUtc(); }

public sealed class SystemClock : IClock
{
  public DateTime NowUtc() { return DateTime.UtcNow; }
}

public sealed class DiscountService
{
  private readonly IClock _clock;
  public DiscountService(IClock clock) { _clock = clock; }

  // 50% off on Black Friday (Nov 27), else 0
  public int GetDiscountPercent()
  {
    DateTime d = _clock.NowUtc().Date;
    if (d.Month == 11 && d.Day == 27) return 50;
    return 0;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    DiscountService live = new DiscountService(new SystemClock());
    Console.WriteLine("Today's discount: " + live.GetDiscountPercent() + "%");
  }
}

การใช้งานตัวจำลองในการทดสอบ

ตัวจำลองใช้งานอินเทอร์เฟซและส่งคืนข้อมูลที่ควบคุมได้ ทำให้การยืนยันผลมีความคงที่

using System;

public interface IClock { DateTime NowUtc(); }

public sealed class FakeClock : IClock
{
  private readonly DateTime _fixed;
  public FakeClock(DateTime fixedUtc) { _fixed = fixedUtc; }
  public DateTime NowUtc() { return _fixed; }
}

public static class Assert
{
  public static void AreEqual(int expected, int actual)
  {
    if (expected != actual)
      throw new Exception("Expected " + expected + " but got " + actual);
  }
}

public sealed class DiscountService
{
  private readonly IClock _clock;
  public DiscountService(IClock clock) { _clock = clock; }

  public int GetDiscountPercent()
  {
    DateTime d = _clock.NowUtc().Date;
    if (d.Month == 11 && d.Day == 27) return 50;
    return 0;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    try
    {
      // Black Friday: 2015-11-27
      DiscountService s1 = new DiscountService(new FakeClock(new DateTime(2015, 11, 27, 0, 0, 0, DateTimeKind.Utc)));
      Assert.AreEqual(50, s1.GetDiscountPercent());

      // Normal day
      DiscountService s2 = new DiscountService(new FakeClock(new DateTime(2015, 11, 26, 0, 0, 0, DateTimeKind.Utc)));
      Assert.AreEqual(0, s2.GetDiscountPercent());

      Console.WriteLine("PASS: discount logic with fake clock");
    }
    catch (Exception ex)
    {
      Console.WriteLine("FAIL: " + ex.Message);
    }
  }
}

สังเกตผลข้างเคียง

ตัวจำลองสามารถบันทึกการเรียกใช้งานได้ ทำให้การทดสอบตรวจสอบผลข้างเคียงได้โดยไม่ต้องส่งอีเมลหรือ SMS จริง

using System;
using System.Collections.Generic;

public interface INotifier { void Send(string message); }

public sealed class OrderService
{
  private readonly INotifier _notifier;
  public OrderService(INotifier notifier) { _notifier = notifier; }

  public void Place(string product, int qty)
  {
    if (qty <= 0) throw new ArgumentOutOfRangeException("qty");
    // ...
    _notifier.Send("Placed: " + product + " x" + qty);
  }
}

public sealed class FakeNotifier : INotifier
{
  public readonly List<string> Messages = new List<string>();
  public void Send(string message) { Messages.Add(message); }
}

public static class Assert
{
  public static void IsTrue(bool condition, string message)
  {
    if (!condition) throw new Exception(message);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    FakeNotifier fake = new FakeNotifier();
    OrderService svc = new OrderService(fake);

    try
    {
      svc.Place("Book", 2);
      Assert.IsTrue(fake.Messages.Count == 1, "Expected exactly one notification");
      Assert.IsTrue(fake.Messages[0].IndexOf("Book") >= 0, "Message should mention product");
      Console.WriteLine("PASS: observed notification via fake");
    }
    catch (Exception ex)
    {
      Console.WriteLine("FAIL: " + ex.Message);
    }
  }
}

ตัวสร้างข้อมูลการทดสอบ

ตัวสร้างขนาดเล็กจะกำหนดค่าเริ่มต้นและเขียนทับเฉพาะสิ่งที่การทดสอบต้องการ ทำให้การเตรียมข้อมูลสั้นและชัดเจน

using System;

public sealed class Order
{
  public string Product;
  public int Quantity;
  public double UnitPrice;

  public double Total() { return Quantity * UnitPrice; }
}

// Minimal builder for tests
public sealed class OrderBuilder
{
  private string _product = "Item";
  private int _qty = 1;
  private double _price = 1.0;

  public OrderBuilder WithProduct(string name) { _product = name; return this; }
  public OrderBuilder WithQty(int qty) { _qty = qty; return this; }
  public OrderBuilder WithPrice(double price) { _price = price; return this; }
  public Order Build()
  {
    Order o = new Order();
    o.Product = _product;
    o.Quantity = _qty;
    o.UnitPrice = _price;
    return o;
  }
}

public static class Assert
{
  public static void AreEqual(double expected, double actual)
  {
    if (Math.Abs(expected - actual) > 0.0001)
      throw new Exception("Expected " + expected + " but got " + actual);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    try
    {
      // Quick setup with readable intent
      Order o = new OrderBuilder()
        .WithProduct("Pen")
        .WithQty(3)
        .WithPrice(2.5)
        .Build();

      Assert.AreEqual(7.5, o.Total());
      Console.WriteLine("PASS: builder created valid order");
    }
    catch (Exception ex)
    {
      Console.WriteLine("FAIL: " + ex.Message);
    }
  }
}

เคล็ดลับเชิงปฏิบัติ

เคล็ดลับ:

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

แนวทางการแยกส่วน

ตรวจสอบอย่างรวดเร็ว: วิธีที่ง่ายที่สุดในการแยกการพึ่งพาออกจากการทดสอบหน่วยคืออะไร

สรุป

สรุป: ฉีดอินเทอร์เฟซ ใช้ตัวจำลองเพื่อควบคุมและสังเกตพฤติกรรม และสร้างข้อมูลนำเข้าอย่างรวดเร็วด้วยตัวสร้างข้อมูลการทดสอบขนาดเล็ก

คำถามที่พบบ่อย

บทเรียน “ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ”

ฉีดการพึ่งพาผ่านอินเทอร์เฟซ เขียนตัวจำลองอย่างง่ายเพื่อสังเกตพฤติกรรม และสร้างข้อมูลเข้าที่ซับซ้อนด้วยตัวสร้างข้อมูลทดสอบขนาดเล็ก คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน

บทเรียน “ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตั้งค่า xUnit/MSTest และการตรวจสอบผล
  2. ตัวจำลองผ่านอินเทอร์เฟซและตัวสร้างข้อมูลทดสอบ
  3. การแก้ไขข้อผิดพลาดของการทดสอบที่ล้มเหลว
← กลับไปที่ C# Academy