0Pricing
C# Academy · 강의

인터페이스를 통한 가짜 객체와 테스트 데이터 작성기

인터페이스를 통해 의존성을 주입하고, 동작을 관찰할 수 있는 간단한 가짜 객체를 작성하며, 작은 테스트 데이터 작성기로 복잡한 입력을 구성합니다.

인터페이스를 통한 가짜 객체와 테스트 데이터 작성기은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 3개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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);
    }
  }
}

부작용 관찰

테스트 대역은 호출을 기록할 수 있으므로 실제 이메일이나 문자 메시지를 보내지 않고도 테스트에서 부작용을 확인할 수 있습니다.

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);
    }
  }
}

실용적인 팁

팁:

  • 부작용을 격리하려면 작은 인터페이스를 우선합니다.
  • 테스트 대역은 작게 유지하고, 필드나 목록에 출력을 기록합니다.
  • 빌더에는 합리적인 기본값과 연쇄 호출이 가능한 설정 메서드를 둡니다.
  • 테스트는 이야기처럼 읽히게 작성합니다: 설정 → 실행 → 검증

격리 방법

간단한 확인: 단위 테스트에서 의존성을 격리하는 가장 간단한 방법은 무엇일까요?

복습

복습: 인터페이스를 주입하고, 동작을 제어하고 관찰하기 위해 테스트 대역을 사용하며, 작은 테스트 데이터 빌더로 입력을 빠르게 만듭니다.

자주 묻는 질문

“인터페이스를 통한 가짜 객체와 테스트 데이터 작성기” 강의는 무료인가요?

네 — “인터페이스를 통한 가짜 객체와 테스트 데이터 작성기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 3개의 강의가 포함되어 있습니다.

“인터페이스를 통한 가짜 객체와 테스트 데이터 작성기”에서 뭘 배우나요?

인터페이스를 통해 의존성을 주입하고, 동작을 관찰할 수 있는 간단한 가짜 객체를 작성하며, 작은 테스트 데이터 작성기로 복잡한 입력을 구성합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 2번째 강의입니다.

“인터페이스를 통한 가짜 객체와 테스트 데이터 작성기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. xUnit/MSTest 설정과 단정
  2. 인터페이스를 통한 가짜 객체와 테스트 데이터 작성기
  3. 실패하는 테스트 디버깅
← C# Academy(으)로 돌아가기