TestDb.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using Domain.Entities.Members;
  2. using Domain.Entities.Payments;
  3. using Domain.Entities.Payments.ValueObject;
  4. using Infrastructure.Persistence;
  5. using Microsoft.EntityFrameworkCore;
  6. // 공유 LocalDB(antooza_test) 기반 통합 테스트 — 병렬 실행 시 싱글턴 Config(최신 row) 를
  7. // 여러 테스트가 동시 seed/read 하여 교차오염된다. 직렬화로 프로덕션의 단일 Config 가정을 보장.
  8. [assembly: Microsoft.VisualStudio.TestTools.UnitTesting.DoNotParallelize]
  9. namespace Application.Tests;
  10. /// <summary>
  11. /// LocalDB 기반 테스트 DB. 운영과 동일한 SQL Server 프로바이더를 사용해
  12. /// rowversion 동시성·유니크 인덱스 등 관계형 동작을 그대로 검증한다.
  13. /// </summary>
  14. [TestClass]
  15. public sealed class TestDb
  16. {
  17. private const string ConnectionString = @"Server=(localdb)\MSSQLLocalDB;Database=antooza_test;Integrated Security=True;TrustServerCertificate=True;";
  18. public static DbContextOptions<AppDbContext> Options { get; } = new DbContextOptionsBuilder<AppDbContext>().UseSqlServer(ConnectionString).Options;
  19. public static AppDbContext Create() => new(Options);
  20. [AssemblyInitialize]
  21. public static void AssemblyInit(TestContext _)
  22. {
  23. using var db = Create();
  24. db.Database.EnsureDeleted();
  25. db.Database.EnsureCreated();
  26. }
  27. public static async Task<int> CreateMemberAsync(AppDbContext db)
  28. {
  29. var member = Member.Create($"test-{Guid.NewGuid():N}@antooza.test");
  30. await db.Member.AddAsync(member);
  31. await db.SaveChangesAsync(default);
  32. return member.ID;
  33. }
  34. public static async Task<PaymentOrder> CreateOrderAsync(AppDbContext db, int memberID, int pointAmount = 10000, bool paid = false)
  35. {
  36. var order = PaymentOrder.Create(memberID, $"ORD-{Guid.NewGuid():N}", "TOSS", pointAmount, PaymentMethod.Integrated);
  37. if (paid)
  38. {
  39. // TossConfirm.PaymentKey 에 unique 인덱스가 있고 테스트 DB 는 어셈블리 단위로 공유되므로
  40. // 주문별 고유 paymentKey(TransactionID)를 부여해 테스트 간 시드 충돌을 방지한다.
  41. order.MarkPaid($"TX-{Guid.NewGuid():N}");
  42. }
  43. await db.PaymentOrder.AddAsync(order);
  44. await db.SaveChangesAsync(default);
  45. return order;
  46. }
  47. }