Geçen hafta birlikte code coverage yapmanın faydaları, çalışma yöntemi, nerelerde kullanıldığına dair alıştırmalar yapmıştık. Bu hafta ise unit test yaparken mock objelerin kullanımından bahsedeceğim. Karmaşık objeleri basitleştirilmiş fonksiyonlarıyla taklit eden objeye Mock objesi denir. Bir birim testi donanım, bağlantı veya başka herhangi bir kaynağı benzetimi açısından Mock objelere ihtiyaç duymaktadır. Çünkü bahsi geçen bu dış kaynak fonksiyonları birim testi kümesinde yer almamaktadırlar. Birim testi aynı zamanda performans için de Mock objelere ihtiyaç duymaktadır. Çünkü canlı sistemde çalışan bir obje çok yüklü olabilir ve bu nesnenin sadece belirli kısımlarına ihtiyaç duyulabilir. Unutulmamalıdır ki test performansı çok önemlidir. Aksi takdirde test çalıştırılması külfete dönüşebilir.
Aşağıdaki sebepler mock nesneleri gerçek nesnelere tercih etmemize neden olur;
- Gerçek nesneler beklenmedik sonuçlar üretir.
- Gerçek nesnelerin oluşumu ve kullanımı zordur.
- Gerçek nesneler yavaştır.
- Gerçek nesneler kullanıcı arayüzüne sahiptir, bu durum yavaş çalışmalarına ve sistemi yormalarına sebep olur.
Şimdi sizlere interface ile yapılmış bir örnek göstereceğim ardından bu örneğimizi mock objesi ile yeniden düzenleyeceğiz.
Görüldüğü üzere IWarehouse adında bir interface oluşturduk. Büyük projeler üzerinde çalışırken bu interfacelerden çokça üretilir ve sistem üzerinde test yaparken zaman kaybına ve birikmelere sebep olur. İşte burada mock objeleri bizim yardımımıza yetişmektedir.
Şimdide yazdığımız kodu mock objesi ile yeniden derleyelim.
Testimizi yazarken takip etmemiz gereken işlem basamakları şu şekilde olmalıdır;
- Oluşturulma anında içinde ürün ve miktar geçen, Order object oluşturun.
- Sonrasında Warehouse adında mock object oluşturulur.
- Mock object ile yapılmak istenen, beklenen durumlar nedir onu belirtiriz. Şöyle ki bu örneğimizde 'HasInventory' metodunun 'true' değer döndürmesi, 'widget' ve '50' parametrelerinin object'e paslanması beklenir.
- Remove metodunun çağırıldığı zaman, null değer döndürmesi (void metod olduğundan) ve 'widget' ile '50' parametrelerinin okunması beklenir.
- Order nesnemizin MockInstance sayesinde yalancı bir nesne oluşturarak içinin doldurulması gerektiği belirlenir.
- Order nesnesinin MockInstance ile doldurulmasının yeterli olup olmadığı doğrulanır.
- Doğrulama işlemi Warehouse adındaki Mock Object içinde yapılır. (Bu doğrulama ancak beklenen bütün metod ve parametreler düzgün çağırıldığı zaman mümkün olur.)
Görüldüğü üzere Mock object'ler gerçek object'lerin birer Proxy object'leridir. Yani
gerçek nesne gibi davranır ama bunun için yazılımcıyı hiçbir class vs yazmak
zorunda bırakmaz. Bir birimin mock objectini elde etmek için virtual olması (bir
interfaceden türemiş olması veya bizzat virtual anahtarıyla işaretlenmiş
olması) gerekir.
Bu haftalık anlatacaklarım bu kadar arkadaşlar. Mock Objeler yaparken en çok dikkatinizi çekmek istediğim muhakkak belli bir interface'den türemiş olmaları gerektiğidir. Birim testleri yazıyoruz fakat ne kadar açık ve kodun iyi derlenmiş olup olmadığının kontrolü gereklidir. Haftaya bu konu üzerinde çalışma yapacağız. Kaliteli birim testlerin hangi özellikte olması gerektiğinden bahsedeceğim. Sizde artık örnekler yapmaya başlayabilirsiniz. Takıldığınız yerler olursa bana mail atabilir ya da yorum bırakabilirsiniz. Haftaya görüşmek üzere hoşçakalın..