Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Birim testi yazmanın birçok avantajı vardır. Regresyona yardımcı olur, belge sağlar ve iyi bir tasarım sağlar. Ancak birim testlerinin okunuşu ve kırılganlıkları zor olduğunda kod tabanınıza zarar verebilir. Bu makalede , .NET Core ve .NET Standard projelerinizi desteklemek üzere birim testleri tasarlamaya yönelik bazı en iyi yöntemler açıklanmaktadır. Testlerinizi dayanıklı ve anlaşılması kolay tutmak için teknikler öğrenirsiniz.
John Reese'a özel teşekkürlerleRoy Osherove'a
Birim testinin avantajları
Aşağıdaki bölümlerde .NET Core ve .NET Standard projeleriniz için birim testleri yazmanın çeşitli nedenleri açıklanmaktadır.
İşlevsel testleri gerçekleştirmek için daha az zaman
İşlevsel testler pahalıdır. Bunlar genellikle uygulamayı açmayı ve beklenen davranışı doğrulamak için sizin (veya başka birinin) izlemesi gereken bir dizi adımı gerçekleştirmeyi içerir. Bu adımlar her zaman test eden tarafından bilinmeyebilir. Testi gerçekleştirmek için bölgede daha bilgili birine ulaşmaları gerekiyor. Testin kendisi önemsiz değişiklikler için saniyeler veya daha büyük değişiklikler için dakikalar sürebilir. Son olarak, bu işlemin sistemde yaptığınız her değişiklik için tekrarlanması gerekir. Öte yandan birim testleri milisaniye alır, bir düğmeye basılarak çalıştırılabilir ve sistem hakkında büyük bir bilgi gerektirmez. Test çalıştırıcısı, testin başarılı mı yoksa başarısız mı olduğunu belirler, kişi değil.
Regresyona karşı koruma
Regresyon hataları, uygulamada bir değişiklik yapıldığında ortaya çıkan hatalardır. Test edenlerin yalnızca yeni özelliklerini test etmekle kalmaz, aynı zamanda mevcut özelliklerin hala beklendiği gibi çalıştığını doğrulamak için önceden var olan özellikleri test etmeleri de yaygındır. Birim testi sayesinde, her derlemeden sonra ve hatta bir kod satırını değiştirdikten sonra tüm test paketinizi yeniden çalıştırabilirsiniz. Bu yaklaşım, yeni kodunuzun mevcut işlevselliği bozmadığı güvenini artırmaya yardımcı olur.
Çalıştırılabilir dokümantasyon
Belirli bir yöntemin ne yaptığı veya belirli bir girişe göre nasıl davrandığı her zaman açık olmayabilir. Kendinize şu soruyu sorabilirsiniz: Boş dize veya null geçirirsem bu yöntem nasıl davranır? İyi adlandırılmış birim testlerinden oluşan bir paketiniz olduğunda, her test belirli bir giriş için beklenen çıkışı açıkça açıklamalıdır. Buna ek olarak, test gerçekten çalıştığını doğrulayabilmelidir.
Daha az bağlı kod
Kod sıkı bir şekilde birleştirildiğinde birim testi yapmak zor olabilir. Yazdığınız kod için birim testleri oluşturmadan, bağlama daha az görünür olabilir. Kodunuz için testler yazmak, kodunuzu doğal olarak birbirinden ayrıştırıyor çünkü aksi takdirde test etmek daha zor.
İyi birim testlerinin özellikleri
İyi bir birim testi tanımlayan birkaç önemli özellik vardır:
- Hızlı: Olgun projelerin binlerce birim testine sahip olması yaygın bir durumdur. Birim testlerinin çalıştırılması çok az zaman almalıdır. Milisaniye.
- Yalıtılmış: Birim testleri tek başınadır, yalıtılmış olarak çalıştırılabilir ve dosya sistemi veya veritabanı gibi dış faktörlere bağımlılıkları yoktur.
- Yinelenebilir: Bir birim testinin çalıştırılması, sonuçlarıyla tutarlı olmalıdır. Çalıştırmalar arasında hiçbir şeyi değiştirmezseniz test her zaman aynı sonucu döndürür.
- Kendi Kendine Denetim: Test, herhangi bir insan etkileşimi olmadan başarılı olup olmadığını otomatik olarak algılamalıdır.
- Zamanında: Birim testinin yazılması test edilen kodla karşılaştırıldığında orantısız bir şekilde uzun sürmemelidir. Kodu test etme işleminin kodu yazmaya kıyasla çok uzun sürdüğünü fark ederseniz, daha test edilebilir bir tasarım düşünün.
Kod kapsamı ve kod kalitesi
Yüksek kod kapsamı yüzdesi genellikle daha yüksek bir kod kalitesiyle ilişkilendirilir. Ancak ölçümün kendisi kodun kalitesini belirleyemez. Aşırı iddialı bir kod kapsamı yüzdesi hedefi belirlemek ters etki yaratabilir. Binlerce koşullu dal içeren karmaşık bir proje düşünün ve 95% kod kapsamı hedefi ayarladığınızı düşünün. Proje şu anda 90% kod kapsamına sahip. Kalan 5% boyunca tüm uç durumları hesaba katmak için gereken süre çok zaman alıcı olabilir ve değer önerisi hızla azalır.
Yüksek kod kapsamı yüzdesi başarı göstergesi değildir ve yüksek kod kalitesi anlamına gelmez. Yalnızca birim testlerinin kapsadığı kod miktarını temsil eder. Daha fazla bilgi için bkz. birim testi kod kapsamı.
Birim testi terminolojisi
Birim testi bağlamında çeşitli terimler sıklıkla kullanılır: sahte , taklit ve kütük. Ne yazık ki bu terimler yanlış uygulanabilir, bu nedenle doğru kullanımı anlamak önemlidir.
Fake: Sahte, taslak veya sahte nesne tanımlamak için kullanılabilecek genel bir terimdir. Nesnenin saplama mı yoksa sahte mi olduğu, nesnenin kullanıldığı bağlama bağlıdır. Başka bir deyişle, bir sahte nesne bir taslak veya bir taklit olabilir.
Mock: Sahte nesne, sistemdeki birim testinin geçip geçmeyeceğine veya başarısız olmasına karar veren sahte bir nesnedir. Taklit bir nesne sahte olarak başlar ve bir
Assert
işlemine girene kadar sahte kalır.saplama : Saptama, sistemdeki mevcut bir bağımlılık (veya ortak çalışan) için denetlenebilir bir değiştirmedir. Saplama kullanarak, doğrudan bağımlılıkla ilgilenmeden kodunuzu test edebilirsiniz. Varsayılan olarak, bir taslak başlangıçta sahte bir işlev gibi çalışır.
Aşağıdaki kodu inceleyin:
var mockOrder = new MockOrder();
var purchase = new Purchase(mockOrder);
purchase.ValidateOrders();
Assert.True(purchase.CanBeShipped);
Bu kod, sahte olarak adlandırılan bir saplama gösterir. Ancak bu senaryoda taslak gerçekten bir taslaktır. Kodun amacı, Purchase
(test altındaki sistem) nesnesinin örneğini oluşturmak için bir araç olarak sırayı geçirmektir.
MockOrder
sınıf adı yanıltıcıdır çünkü nesne bir mock değil, bir stub'dır.
Aşağıdaki kod daha doğru bir tasarım gösterir:
var stubOrder = new FakeOrder();
var purchase = new Purchase(stubOrder);
purchase.ValidateOrders();
Assert.True(purchase.CanBeShipped);
sınıfı FakeOrder
olarak yeniden adlandırıldığında, sınıf daha genel olur. Sınıf, test çalışması gereksinimlerine göre sahte veya saplama olarak kullanılabilir. İlk örnekte, FakeOrder
sınıfı saplama olarak kullanılır ve Assert
işlemi sırasında kullanılmaz. Kod, oluşturucunun gereksinimlerini karşılamak için FakeOrder
sınıfını Purchase
sınıfına geçirir.
sınıfını sahte olarak kullanmak için kodu güncelleştirebilirsiniz:
var mockOrder = new FakeOrder();
var purchase = new Purchase(mockOrder);
purchase.ValidateOrders();
Assert.True(mockOrder.Validated);
Bu tasarımda kod, sahte üzerinde bir özelliği denetler (bunu doğrular) ve bu nedenle mockOrder
sınıfı bir mock'tur.
Önemli
Terminolojiyi doğru uygulamak önemlidir. Saplamalarınıza "sahte" derseniz, diğer geliştiriciler amacınız hakkında yanlış varsayımlarda bulunur.
Mocklar ve stublar hakkında hatırlanması gereken en önemli nokta, Assert
işlemi dışında mockların stublar gibi olmasıdır.
Assert
işlemleri bir sahte nesneye karşı çalıştırırsınız, ancak saplamaya karşı çalıştırmazsınız.
En iyi yöntemler
Birim testleri yazarken izleyebileceğiniz birkaç önemli en iyi yöntem vardır. Aşağıdaki bölümlerde, kodunuz için en iyi yöntemlerin nasıl uygulanacağını gösteren örnekler verilmiştir.
Altyapı bağımlılıklarından kaçınma
Birim testleri yazarken altyapıya bağımlılıklar eklememeye çalışın. Bağımlılıklar, testleri yavaş ve kırılgan hale getirir ve tümleştirme testleri için ayrılmalıdır. Açık Bağımlılıklar İlkesi izleyerek ve .NET bağımlılık eklemekullanarak uygulamanızda bu bağımlılıklardan kaçınabilirsiniz. Birim testlerinizi tümleştirme testlerinden ayrı bir projede de tutabilirsiniz. Bu yaklaşım, birim testi projenizin altyapı paketlerine yönelik başvuruları veya bağımlılıkları olmamasını sağlar.
Test adlandırma standartlarına uyun
Testinizin adı üç bölümden oluşmalıdır:
- Test edilen yöntemin adı
- Yöntemin test edildiği senaryo
- Senaryo çağrıldığında beklenen davranış
Adlandırma standartları, test amacını ve uygulamasını ifade etmeye yardımcı olduğundan önemlidir. Testler, kodunuzun çalıştığından emin olmaktan daha fazlasıdır. Belgeleri de sağlıyorlar. Birim testleri paketine bakarak kodunuzun davranışını çıkarabilmeniz ve kodun kendisine bakmanız gerekmemelidir. Ayrıca, testler başarısız olduğunda, beklentilerinizi tam olarak hangi senaryoların karşılamadığı görebilirsiniz.
Özgün kod
[Fact]
public void Test_Single()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
En iyi uygulamaları uygula
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
Testlerinizi düzenleyin
"Düzenleme, Eylem, Onay" deseni, birim testleri yazmak için yaygın bir yaklaşımdır. Adından da anlaşılacağı gibi, desen üç ana görevden oluşur:
- Nesnelerinizi düzenleyin, bunları gerektiği gibi oluşturun ve yapılandırın
- Nesne üzerinde
- Bir şeyin beklendiği gibi olduğunu doğrula
Deseni uyguladığınızda, test edilenleri Yerleştir ve Onayla görevlerinden açıkça ayırabilirsiniz. Desen, onayların Act görevindeki kodla kesişmesi fırsatını azaltmaya da yardımcı olur.
Okunabilirlik, birim testi yazarken en önemli yönlerden biridir. Test içindeki her desen eylemini ayırmak kodunuzu çağırmak için gereken bağımlılıkları, kodunuzun nasıl çağrıldığını ve onaylamaya çalıştığınız şeyi açıkça vurgular. Bazı adımları birleştirmek ve testinizin boyutunu küçültmek mümkün olsa da, genel hedef testi mümkün olduğunca okunabilir hale getirmektir.
Özgün kod
[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();
// Assert
Assert.Equal(0, stringCalculator.Add(""));
}
En iyi uygulamaları uygula
[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();
// Act
var actual = stringCalculator.Add("");
// Assert
Assert.Equal(0, actual);
}
Asgari geçiş testleri yazma
Birim testinin girişi, şu anda test etmekte olduğunuz davranışı doğrulamak için gereken en basit bilgiler olmalıdır. Minimalist yaklaşım, testlerin kod tabanındaki gelecekteki değişikliklere karşı daha dayanıklı hale gelmesine ve uygulama üzerindeki davranışı doğrulamaya odaklanmasına yardımcı olur.
Geçerli testi geçmek için gerekenden daha fazla bilgi içeren testlerin teste hata ekleme şansı daha yüksektir ve testin amacını daha az net hale getirebilirsiniz. Testler yazarken davranışa odaklanmak istiyorsunuz. Modellerde ek özellikler ayarlamak veya gerekli olmadığında sıfır olmayan değerler kullanmak, yalnızca onaylamaya çalıştığınız şeyi zayıflatır.
Özgün kod
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("42");
Assert.Equal(42, actual);
}
En iyi uygulamaları uygula
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
Sihirli dizelerden kaçının
Magic dizeleri, herhangi bir kod ek açıklaması veya bağlamı olmadan doğrudan birim testlerinizde sabit kodlanmış dize değerleridir. Bu değerler kodunuzun daha az okunabilir olmasını ve bakımının zor olmasını sağlar. Sihirli dizeler, testlerinizin okuyucusunun kafa karışıklığına neden olabilir. Bir dize olağan dışı görünüyorsa, parametre veya dönüş değeri için belirli bir değerin neden seçildiğini merak edebilir. Bu tür dize değeri, teste odaklanmak yerine uygulama ayrıntılarına daha yakından bakmalarına neden olabilir.
Tavsiye
Birim test kodunuzda mümkün olduğunca çok amacı ifade etme hedefinizi oluşturun. Sihirli dizeleri kullanmak yerine sabitlere sabit kodlanmış değerler atayın.
Özgün kod
[Fact]
public void Add_BigNumber_ThrowsException()
{
var stringCalculator = new StringCalculator();
Action actual = () => stringCalculator.Add("1001");
Assert.Throws<OverflowException>(actual);
}
En iyi uygulamaları uygula
[Fact]
void Add_MaximumSumResult_ThrowsOverflowException()
{
var stringCalculator = new StringCalculator();
const string MAXIMUM_RESULT = "1001";
Action actual = () => stringCalculator.Add(MAXIMUM_RESULT);
Assert.Throws<OverflowException>(actual);
}
Birim testlerinde kodlama mantığını kullanmaktan kaçının
Birim testlerinizi yazarken, el ile dize birleştirme, if
, while
, for
ve switch
gibi mantıksal koşullardan ve diğer koşullardan kaçının. Test paketinize mantık eklerseniz hata ekleme şansı önemli ölçüde artar. Hata bulmak istediğiniz son yer, test paketinizin içindedir. Testlerinizin çalıştığından emin olmanız gerekir, aksi takdirde bunlara güvenemezsiniz. Güvenmediğiniz testler herhangi bir değer sağlamaz. Test başarısız olduğunda, kodunuzla ilgili bir sorun olduğunu hisseder ve bunun göz ardı edilemeyeceğini fark edersiniz.
Tavsiye
Testinize mantık eklemek kaçınılmaz görünüyorsa, mantık gereksinimlerini sınırlamak için testi iki veya daha fazla farklı teste bölmeyi göz önünde bulundurun.
Özgün kod
[Fact]
public void Add_MultipleNumbers_ReturnsCorrectResults()
{
var stringCalculator = new StringCalculator();
var expected = 0;
var testCases = new[]
{
"0,0,0",
"0,1,2",
"1,2,3"
};
foreach (var test in testCases)
{
Assert.Equal(expected, stringCalculator.Add(test));
expected += 3;
}
}
En iyi uygulamaları uygula
[Theory]
[InlineData("0,0,0", 0)]
[InlineData("0,1,2", 3)]
[InlineData("1,2,3", 6)]
public void Add_MultipleNumbers_ReturnsSumOfNumbers(string input, int expected)
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add(input);
Assert.Equal(expected, actual);
}
Kurulum ve Yırtma yerine yardımcı yöntemleri kullanma
Testleriniz için benzer bir nesneye veya duruma ihtiyacınız varsa, Setup
ve Teardown
öznitelikleri yerine yardımcı bir yöntem kullanın. Yardımcı yöntemler, çeşitli nedenlerle bu öznitelikler yerine tercih edilir:
- Tüm kod her testin içinden görünür olduğundan testleri okurken daha az karışıklık
- Verilen test için aşırı veya yetersiz ayarlama yapma olasılığı daha az.
- Testler arasında durum paylaşma olasılığı daha azdır ve bu da aralarında istenmeyen bağımlılıklar oluşturur
Birim testi çerçevelerinde Setup
özniteliği, test paketinizdeki her birim testinden önce çağrılır. Bazı programcılar bu davranışı yararlı olarak görür, ancak genellikle şişmiş ve okuması zor testlere neden olur. Her test genellikle kurulum ve yürütme için farklı gereksinimlere sahiptir. Ne yazık ki, Setup
özniteliği sizi her test için tam olarak aynı gereksinimleri kullanmaya zorlar.
Uyarı
SetUp
ve TearDown
öznitelikleri xUnit sürüm 2.x ve sonraki sürümlerde kaldırılır.
Özgün kod
En iyi uygulamaları uygula
private readonly StringCalculator stringCalculator;
public StringCalculatorTests()
{
stringCalculator = new StringCalculator();
}
[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var stringCalculator = CreateDefaultStringCalculator();
var actual = stringCalculator.Add("0,1");
Assert.Equal(1, actual);
}
// More tests...
// More tests...
[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var result = stringCalculator.Add("0,1");
Assert.Equal(1, result);
}
private StringCalculator CreateDefaultStringCalculator()
{
return new StringCalculator();
}
Birden çok Eylem görevinden kaçının
Testlerinizi yazarken, test başına yalnızca bir Act görevi eklemeyi deneyin. Tek bir Act görevini uygulamaya yönelik yaygın yaklaşımlardan bazıları, her Bir Eylem için ayrı bir test oluşturmak veya parametreli testler kullanmaktır. Her test için tek bir Act görevi kullanmanın çeşitli avantajları vardır:
- Test başarısız olursa hangi Act görevinin başarısız olduğunu kolayca anlayabilirsiniz.
- Testin yalnızca tek bir olaya odaklandığından emin olabilirsiniz.
- Testlerinizin neden başarısız olduğunu net bir şekilde görebilirsiniz.
Birden çok Eylem görevinin tek tek onaylanması gerekir ve tüm Assert görevlerinin yürütüldüğünü garantileyemezsiniz. Çoğu birim testi çerçevesinde, bir Assert görevi birim testinde başarısız olduktan sonra, sonraki tüm testler otomatik olarak başarısız olarak kabul edilir. Bazı çalışma işlevleri başarısız olarak yorumlandığı için işlem kafa karıştırıcı olabilir.
Özgün kod
[Fact]
public void Add_EmptyEntries_ShouldBeTreatedAsZero()
{
// Act
var actual1 = stringCalculator.Add("");
var actual2 = stringCalculator.Add(",");
// Assert
Assert.Equal(0, actual1);
Assert.Equal(0, actual2);
}
En iyi uygulamaları uygula
[Theory]
[InlineData("", 0)]
[InlineData(",", 0)]
public void Add_EmptyEntries_ShouldBeTreatedAsZero(string input, int expected)
{
// Arrange
var stringCalculator = new StringCalculator();
// Act
var actual = stringCalculator.Add(input);
// Assert
Assert.Equal(expected, actual);
}
Genel yöntemlerle özel yöntemleri doğrulama
Çoğu durumda, kodunuzda özel bir yöntemi test etmeniz gerekmez. Özel yöntemler bir uygulama ayrıntısıdır ve hiçbir zaman yalıtımlı olarak mevcut olmaz. Geliştirme sürecinin bir noktasında, özel yöntemi uygulamanın bir parçası olarak çağırmak için genel kullanıma yönelik bir yöntem tanıtırsınız. Birim testlerinizi yazarken önemsediğiniz şey, özel olanı çağıran genel yöntemin sonucudur.
Aşağıdaki kod senaryolarını göz önünde bulundurun:
public string ParseLogLine(string input)
{
var sanitizedInput = TrimInput(input);
return sanitizedInput;
}
private string TrimInput(string input)
{
return input.Trim();
}
Test açısından ilk tepkiniz, beklendiği gibi çalıştığından emin olmak için TrimInput
yöntemi için bir test yazmak olabilir. Ancak, ParseLogLine
yöntemi sanitizedInput
nesnesini beklemediğiniz bir şekilde işler. Bilinmeyen davranış, TrimInput
yöntemine karşı testinizi işe yaramaz hale getirebilir.
Bu senaryoda daha iyi bir test, genel kullanıma yönelik ParseLogLine
yöntemini doğrulamaktır:
public void ParseLogLine_StartsAndEndsWithSpace_ReturnsTrimmedResult()
{
var parser = new Parser();
var result = parser.ParseLogLine(" a ");
Assert.Equals("a", result);
}
Özel bir yöntemle karşılaştığınızda, özel yöntemi çağıran ortak yöntemi bulun ve testlerinizi public yöntemine karşı yazın. Özel bir yöntemin beklenen sonucu döndürmesi, sonunda özel yöntemi çağıran sistemin sonucu doğru kullandığı anlamına gelmez.
Kütük statik referansları dikişlerle yönetme
Birim testinin bir ilkesi, test altındaki sistemin tam denetimine sahip olması gerektiğidir. Ancak bu ilke, üretim kodu statik başvurulara (örneğin, DateTime.Now
) yönelik çağrılar içerdiğinde sorunlu olabilir.
Aşağıdaki kod senaryolarını inceleyin:
public int GetDiscountedPrice(int price)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}
Bu kod için birim testi yazabilir misiniz?
price
üzerinde bir Assert görevi çalıştırmayı deneyebilirsiniz:
public void GetDiscountedPrice_NotTuesday_ReturnsFullPrice()
{
var priceCalculator = new PriceCalculator();
var actual = priceCalculator.GetDiscountedPrice(2);
Assert.Equals(2, actual)
}
public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()
{
var priceCalculator = new PriceCalculator();
var actual = priceCalculator.GetDiscountedPrice(2);
Assert.Equals(1, actual);
}
Ne yazık ki, testinizde bazı sorunlar olduğunu hemen fark ediyorsunuz:
- Test paketi Salı günü çalıştırılırsa, ikinci test geçer, ancak ilk test başarısız olur.
- Test paketi başka bir gün çalıştırılırsa, ilk test geçer, ancak ikinci test başarısız olur.
Bu sorunları çözmek için üretim kodunuza bir dikiş eklemeniz gerekir. Bir yaklaşım, bir arabirimde denetlemeniz gereken kodu sarmalayıp üretim kodunun bu arabirime bağımlı olmasını sağlamaktır:
public interface IDateTimeProvider
{
DayOfWeek DayOfWeek();
}
public int GetDiscountedPrice(int price, IDateTimeProvider dateTimeProvider)
{
if (dateTimeProvider.DayOfWeek() == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}
Ayrıca test paketinizin yeni bir sürümünü de yazmanız gerekir:
public void GetDiscountedPrice_NotTuesday_ReturnsFullPrice()
{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Monday);
var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);
Assert.Equals(2, actual);
}
public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()
{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Tuesday);
var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);
Assert.Equals(1, actual);
}
Artık test paketi DateTime.Now
değeri üzerinde tam denetime sahiptir ve metoda çağrıldığında herhangi bir değerin yedeğini alabilir.