Sahte nesneler genel olarak nasıl kötüye kullanılır?


15

Kısa bir süre önce sahte nesnelerin yanlış anlaşıldığını ve yanlış kullanıldığını söyleyen bir makale okudum. Dikkat edebileceğim net alaycı kalıplar var mı?



hayır ... tam kaynağı hatırlayamıyorum ama eğer gönderirsem burada gönderirim
Armand

Mongodb API'sini alay etmek için stackoverflow üzerinde görev aldım. Kendiniz yazmadığınız herhangi bir sınıfı alay etmenin yanlış olduğunu iddia eden bir blog gönderisine yönlendirildim. Aslında buna katılmıyorum ama görüş dışarıda.
Kevin

Yanıtlar:


13

Basit somut derslerin alay konusu olmasından nefret ediyorum. Örneğin, başka hiçbir şeye bağımlılığı olmayan aşağıdaki basit sınıfı ele alalım:

public class Person
{
    private readonly string _firstName;
    private readonly string _surname;

    public Person(string firstName, string surname)
    {
        if (String.IsNullOrEmpty(firstName))
        {
            throw new ArgumentException("Must have first name");
        }

        if (String.IsNullOrEmpty(surname))
        {
            throw new ArgumentException("Must have a surname");
        }

        _firstName = firstName;
        _surname = surname;
    }

    public string Name 
    {
        get
        {
            return _firstName + " " + _surname;
        }
    }
}

Bu sınıfı içeren herhangi bir testte, 'IPerson' çıkarılması, alay konusu olan ve kullanılan beklentiler gibi bazı arayüzlerden ziyade gerçek bir örnek oluşturulmuş ve kullanılmıştır. Gerçek olanı kullanarak testiniz daha gerçekçi olur (parametre kontrolleri yerinde ve 'Ad' özelliğinin gerçek uygulamasına sahip olursunuz). Bunun gibi basit bir sınıf için, testlerinizi daha yavaş, daha az belirleyici veya mantıksallaştırmazsınız (başka bir sınıfı test ederken Adın çağrıldığını bilmeniz gerekmez) - alay etmenin / stubbing.

Bunun bir uzantısı olarak, insanların sahte bir beklenti ile kurulduğu testler yazdıklarını gördüm, o zaman sahte doğrudan testte çağrılır. Şaşırtıcı olmayan bir şekilde test her zaman geçecektir ... hmmmm ...


Neyse ki kullandığım alaycı çerçeveler somut sınıflarla alay edebildi, bu yüzden arayüzleri uygunsuz noktalarda çıkarmak sorun değil.
Armand

5
Bu, sorunu değiştirmez - bu tür basit şeyler, alay konusu olabilecek teknik kısıtlamaları hafifleten bir şey kullansanız bile genellikle alay edilmemelidir (örneğin, TypeMock veya dinamik bir dil gibi sahte bir çerçeve).
FinnNk

Temel kuralım veri için değil, davranış için alay etmek olmuştur.
ardave

10

Kulağa bariz gelebilir, ancak: Üretim kodunda sahte nesneler kullanmayın! Üretim kodunun bazı sahte nesnelerin özelliklerine bağlı olduğu birden fazla örnek gördüm ( MockHttpServletRequestörneğin Springframework'tan).


14
umarım kutsal görevinizi yerine getirmiş ve kodu DailyWTF'e göndermişsinizdir?
keppla

1
Önceki çalışmamda kod tabanımızdan DWTF'ye bir şey göndermemiz kesinlikle yasaklanmıştı.
quant_dev

9
@quant_dev: Böyle bir politikaya sahip olmaları geliştiricileri hakkında korkunç şeyler ima ediyor ...
John Fisher

1
Pek sayılmaz. Bir ürünü satmak için hızlı bir şekilde bir kod tabanı geliştirmesi gereken bir girişimdi ve daha sonra ürün olgunlaştıkça ve daha fazla geliştirme ilk tasarımın (eksikliği) nedeniyle engellendiğinden, teknik borcu ödemek için birleştirmeye ve yeniden düzenlemeye başladı. Yöneticiler eski kod tabanının bok olduğunu biliyorlardı ve yeniden kaynak oluşturmak için zaman ve kaynak harcadılar, ancak olumsuz bir tanıtım riskini almak istemediler.
quant_dev

Sadece kısayolları almak gerçekten sadece günlük almak için yeterli değil ...
poolie

9

Bence alaylarda aşırı yöntem çağırma kontrolü. Bu, daha önce tam olarak belirtilmeyen bir ek yöntem çağırma olduğunda varsayılan sahte davranışın başarısız olduğu EasyMock gibi birkaç alaycı çerçeve tarafından zorlanan bir uygulama olduğunu hissediyorum. Bu tür katı sahte yöntem kontrolü, koddaki en küçük değişikliğin, çekirdek işlevselliği hala aynı olsa bile, bir dizi testin başarısız olmasına yol açabilen kırılgan tasarımlara yol açabilir.

Buna bir çözüm, alay yerine koçan kullanmaya başlıyor. Konu hakkında özellikle aydınlatıcı bulduğum bir makale Mockito'nun Javadoc'unda bulunan bir makaleydi: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (bkz. "2. Bazı stubbing?" ), bağlantı: http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/ .

Şimdiye kadar Mockito ile çalışmaktan zevk aldım çünkü bu sıkı alaycı davranışı değil, bunun yerine taslakların kullanımını zorlamıyor. Ayrıca, tüm sahte nesne yerine belirli olanlar üzerinde yöntem denetimi uygular; böylece yalnızca test senaryosunda gerçekten önemli olan yöntemleri kontrol edersiniz.

Burada birkaç kitap var ve orada bu konuya dokunmak ve alaycı ve genel tavsiye ederim:

xBirim Kalıpları

Birim Testi Sanatı: .Net'teki Örneklerle

Yeni Nesil Java Testi: TestNG ve Gelişmiş Kavramlar (bu kitap çoğunlukla testNG ile ilgilidir, ancak alayla ilgili güzel bir bölüm vardır)


Aşırı yöntem çağırma kontrolleri noktası için +1. Bununla birlikte, madalyonun her zaman beklenmeyen bir yöntem çağırma yönteminde bir başarısızlığa neden olduğu flip tarafı vardır. Neyse ki Mockito bunu Answer.RETURNS_SMART_NULLSteşhis etmeye yardımcı olan alaylar ayarına sahiptir .
Bringer128

4

Deneyimlerimde az sayıda anti-desen gözlemledim.

  • Durum değişikliğinin gerçekleşebileceği ve doğrulanması gereken yerlerde alay edilen / saplanan etki alanı sınıfları.
  • Entegrasyon testlerinin amacını yenen bir dizi sahte ve somut sınıfla etkileşime giren entegrasyon testleri.
  • Üretim kodunda yanlışlıkla sahte kullanım (Bu asla olmamalı)

Aksi takdirde alay ile özellikle Mockito deneyimim bir esinti oldu. Testleri yazmak ve bakımını çok kolay hale getirdiler. GWT görüntüleme / sunucu etkileşim testi, alaylarla GWTTestCase'den çok daha kolaydır.


2 & 3 kesin problemlerdir! Basit bir örneğiniz var mı (1)?
Armand

2

Bir uygulamanın birden fazla katmanında alayları kullanan testlerin, deşifre edilmesi ve değiştirilmesi özellikle zor olduğunu düşünüyorum. Ancak bunun son yıllarda geliştirilmiş sahte çerçeve API'leri (uygun olduğunda JMock kullanıyorum) tarafından azaltıldığını düşünüyorum.

5 veya 6 yıl önce API'ler EasyMock gibi güçlü ancak çok hantaldı. Genellikle kullanılan test kodu, test ettiği koddan daha karmaşık büyüklük dereceleriydi. O zamanlar çok dikkatli bir şekilde kullanmak için bulunduğum ekipleri etkilemeye çalıştım ve özellikle test için arayüzlerin alternatif uygulamaları olan basit el yapımı alaylarla uğraştım.

Son zamanlarda alaycı API'lar onları daha okunabilir kullanan testler yaptıkları için bu konudaki güçlü görüşlerim daha yumuşak hale geldi. Temelde kodumun (testler dahil) diğer geliştiriciler tarafından belirsiz API çağrıları bir eleme yoluyla eleme gibi hissettirmeden değiştirilebilir olmasını istiyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.