Özet - Test temelleri
[Fact], [Theory] ve Mock'u birleştirerek bir hesap makinesi testi yazarsın.
Test temellerini hatırla
Bu grupta xUnit'in temellerini gördük: [Fact] tek senaryoyu, [Theory] + [InlineData] parametreli testi, Assert doğrulamayı (Equal, True, Throws) ve Mock<T> ile dış bağımlılığın izole edilmesini öğrendik.
İyi bir test üç özelliğe sahiptir: hızlı (saniyede binlerce), bağımsız (sıra önemli değil) ve okunaklı (başarısızlık nedeni belli). Şimdi öğrendiklerimizi birleşik bir örnekte uygulayacağız.
Uygulama StringUtils için birleşik test
FactAttribute ve statik Assert sınıfını tanımla; Assert.Equal<T>, Assert.True(bool) ve Assert.Throws<T>(Action) metotları olsun. StringUtils.Capitalize(string) metodu boş giriş için ArgumentException fırlatsın, değilse ilk harfi büyültüp döndürsün. StringUtilsTests içinde üç [Fact] metodu yaz: TestCapitalizesLower Assert.Equal("Merhaba", StringUtils.Capitalize("merhaba")); TestReturnsSameWhenCapital Assert.True(StringUtils.Capitalize("A") == "A"); TestEmptyThrows Assert.Throws<ArgumentException>(() => StringUtils.Capitalize("")) çağrısı yapsın. Main üçünü çalıştırıp "Test passed: Capitalize checks" yazsın.
Örnek çözümü göster
Attribute { } tanımla. static class Assert { public static void Equal<T>(T e, T a) { if (!EqualityComparer<T>.Default.Equals(e, a)) throw new Exception(); } public static void True(bool c) { if (!c) throw new Exception(); } public static void Throws<T>(Action a) where T : Exception { try { a(); } catch (T) { return; } throw new Exception(); } } yaz. class StringUtils { public static string Capitalize(string text) { if (string.IsNullOrEmpty(text)) throw new ArgumentException(); return char.ToUpper(text[0]) + text.Substring(1); } } yaz. class StringUtilsTests { [Fact] public void TestCapitalizesLower() { Assert.Equal("Merhaba", StringUtils.Capitalize("merhaba")); } [Fact] public void TestReturnsSameWhenCapital() { Assert.True(StringUtils.Capitalize("A") == "A"); } [Fact] public void TestEmptyThrows() { Assert.Throws<ArgumentException>(() => StringUtils.Capitalize("")); } } yaz. Main'de üç metodu çağırıp Console.WriteLine("Test passed: Capitalize checks");
Örnek çözüm:
using System;
class FactAttribute : Attribute { }
static class Assert
{
public static void Equal<T>(T expected, T actual)
{
if (!EqualityComparer<T>.Default.Equals(expected, actual))
throw new Exception($"Beklenen {expected}, gerçek {actual}");
}
public static void True(bool condition)
{
if (!condition) throw new Exception("Beklenen: doğru");
}
public static void Throws<T>(Action action) where T : Exception
{
try { action(); }
catch (T) { return; }
throw new Exception("Beklenen istisna fırlatılmadı");
}
}
class StringUtils
{
public static string Capitalize(string text)
{
if (string.IsNullOrEmpty(text)) throw new ArgumentException();
return char.ToUpper(text[0]) + text.Substring(1);
}
}
class StringUtilsTests
{
[Fact]
public void TestCapitalizesLower()
{
Assert.Equal("Merhaba", StringUtils.Capitalize("merhaba"));
}
[Fact]
public void TestReturnsSameWhenCapital()
{
Assert.True(StringUtils.Capitalize("A") == "A");
}
[Fact]
public void TestEmptyThrows()
{
Assert.Throws<ArgumentException>(() => StringUtils.Capitalize(""));
}
}
class Program
{
static void Main()
{
var tests = new StringUtilsTests();
tests.TestCapitalizesLower();
tests.TestReturnsSameWhenCapital();
tests.TestEmptyThrows();
Console.WriteLine("Test passed: Capitalize checks");
}
}
Uygulama StringUtils.Repeat için [Theory]
FactAttribute, TheoryAttribute, InlineDataAttribute (params object[] kuruculu) ve statik Assert sınıflarını tanımla. StringUtils.Repeat(string text, int count) metodu text'i count kez birleştirip döndürsün. StringUtilsTests.TestRepeat metodu [Theory] ile işaretlenip üç [InlineData] satırı alsın: ("a", 3, "aaa"), ("ab", 2, "abab"), ("x", 1, "x"). Gövde Assert.Equal(expected, StringUtils.Repeat(text, count)) çağrısı yapsın. Main testi ("a", 3, "aaa") ile çağırıp "Test passed: Theory Repeat(a,3)=aaa" yazsın.
Örnek çözümü göster
Attribute { } ve class InlineDataAttribute : Attribute { public InlineDataAttribute(params object[] data) { } } tanımla. static class Assert { public static void Equal<T>(T e, T a) { if (!EqualityComparer<T>.Default.Equals(e, a)) throw new Exception(); } } yaz. class StringUtils { public static string Repeat(string text, int count) { string r = ""; for (int i = 0; i < count; i++) r += text; return r; } } yaz. class StringUtilsTests { [Theory] [InlineData("a", 3, "aaa")] [InlineData("ab", 2, "abab")] [InlineData("x", 1, "x")] public void TestRepeat(string text, int count, string expected) { Assert.Equal(expected, StringUtils.Repeat(text, count)); } } yaz. Main'de: var t = new StringUtilsTests(); t.TestRepeat("a", 3, "aaa"); Console.WriteLine("Test passed: Theory Repeat(a,3)=aaa");
Örnek çözüm:
using System;
class FactAttribute : Attribute { }
class TheoryAttribute : Attribute { }
class InlineDataAttribute : Attribute
{
public InlineDataAttribute(params object[] data) { }
}
static class Assert
{
public static void Equal<T>(T expected, T actual)
{
if (!EqualityComparer<T>.Default.Equals(expected, actual))
throw new Exception($"Beklenen {expected}, gerçek {actual}");
}
}
class StringUtils
{
public static string Repeat(string text, int count)
{
string result = "";
for (int i = 0; i < count; i++) result += text;
return result;
}
}
class StringUtilsTests
{
[Theory]
[InlineData("a", 3, "aaa")]
[InlineData("ab", 2, "abab")]
[InlineData("x", 1, "x")]
public void TestRepeat(string text, int count, string expected)
{
Assert.Equal(expected, StringUtils.Repeat(text, count));
}
}
class Program
{
static void Main()
{
var tests = new StringUtilsTests();
tests.TestRepeat("a", 3, "aaa");
Console.WriteLine("Test passed: Theory Repeat(a,3)=aaa");
}
}
Kendini test et
-
Test kavramlarını eşleştir
- [Fact]
- Tek senaryo
- [Theory]
- Parametreli test
- Assert.Throws
- Hata yolu
- Mock<T>
- Sahte bağımlılık
-
Parametreli test hangi öznitelikle yazılır?
- [Fact]
- [Theory]
- [Setup]
- [Test]
Cevabı göster
[Theory] — Doğru. [Theory] + [InlineData] parametreli testi tanımlar.