Alaycı beton sınıfı - Tavsiye edilmez


11

Ben sadece beton sınıf alay tavsiye edilmeyen bazı nedenleri açıklayan bir "Nesne Odaklı Yazılım Büyüyen" bir alıntı okudum.

Burada MusicCentre sınıfı için bir birim test örneği:

public class MusicCentreTest {
  @Test public void startsCdPlayerAtTimeRequested() {
    final MutableTime scheduledTime = new MutableTime();
    CdPlayer player = new CdPlayer() { 
      @Override 
      public void scheduleToStartAt(Time startTime) {
        scheduledTime.set(startTime);
      }
    }

    MusicCentre centre = new MusicCentre(player);
    centre.startMediaAt(LATER);

    assertEquals(LATER, scheduledTime.get());
  }
}

Ve ilk açıklaması:

Bu yaklaşımdaki sorun, nesneler arasındaki ilişkiyi örtük bırakmasıdır. Umarım şimdiye kadar, Mock Nesneleri ile Test Odaklı Geliştirmenin amacının nesneler arasındaki ilişkileri keşfetmek olduğunu açıkladık. Alt sınıf varsa, böyle bir ilişki görünür yapmak için etki alanı kodunda hiçbir şey, sadece bir nesne yöntemleri. Bu, bu ilişkiyi destekleyen hizmetin başka bir yerde alakalı olup olmadığını görmeyi zorlaştırır ve bir dahaki sefere sınıfla çalıştığımda analizi tekrar yapmak zorunda kalacağım.

Ne zaman dediğini tam olarak anlayamıyorum:

Bu, bu ilişkiyi destekleyen hizmetin başka bir yerde alakalı olup olmadığını görmeyi zorlaştırır ve bir dahaki sefere sınıfla çalıştığımda analizi tekrar yapmak zorunda kalacağım.

Hizmetin MusicCentreadı verilen yönteme karşılık geldiğini anlıyorum startMediaAt.

"Başka bir yerde" ile ne demek istiyor?

Tüm alıntı burada: http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html


Bu alıntılardan ne kastettiğini anlayamadığım için bloguna bir yorum ekledim.
oligofren

@oligofren Gerçekten harika bir muamma :) ...
Mik378

Yanıtlar:


6

Bu yazının yazarı, üye sınıfların kullanımı üzerinde arabirimlerin kullanımını teşvik ediyor.

It turns out that my MusicCentre object only uses the starting and stopping methods on the CdPlayer, the rest are used by some other part of the system. I'm over-specifying my MediaCentre by requiring it to talk to a CdPlayer, what it actually needs is a ScheduledDevice.

Daha sonra yeniden keşfetme konusunda endişe duyduğu ilişki, MediaCentre sınıfının tüm CdPlayer nesnesine ihtiyaç duymamasıdır. Onun iddiası, bir Arayüz (muhtemelen sadece başlat | durdur ile sınırlı) kullanarak etkileşimin gerçekte ne olduğunu anlamanın daha kolay olduğudur.

"başka bir yerde", basitçe diğer nesnelerin benzer şekilde sınırlı ilişkilere sahip olabileceği ve tam üye nesnesinin gerekli olmadığı anlamına gelir - bir Arayüz ile sarılmış işlevselliğin bir alt kümesi yeterli olmalıdır.

Talep, tüm potansiyel işlevleri patlattığınızda daha anlamlı olmaya başlar:

  • Başlat
  • Dur
  • Duraklat
  • kayıt
  • rastgele oyun sırası
  • örnek parçalar, şarkının başlangıcı
  • örnek parçalar, rasgele şarkı örneği
  • medya bilgisi sağlamak
  • ...

Şimdi onun "Sadece başlat ve durdur 'a ihtiyacım" iddiası daha anlamlı. Bir Arayüz yerine somut üye nesnesinin kullanılması, gelecekteki geliştiriciler için gerçekten neyin gerekli olduğunu daha az netleştirir . CdPlayer içindeki diğer tüm işlevler üzerinde MediaCentre'den birim testleri çalıştırmak, "umursamama" durumuna ait oldukları için test etme zahmetidir. Eğer Recordfonksiyon bu durumda çalışma değildi gerekli olmadığı için, biz gerçekten umurumda değil. Ancak gelecekteki bir bakıcı, kodun yazıldığı gibi dayanması gerekmeyebilir.

Nihayetinde, yazarın önermesi sadece gerekli olanı kullanmak ve gelecekteki bakıcılara daha önce gerekli olanları açıkça belirtmektir. Amaç, sonraki bakım sırasında kod modülünün yeniden çalışmasını / yeniden analizini en aza indirmektir.


Bu harika cevap için teşekkürler. Ancak şunu söylediniz: "Diğer tüm işlevler üzerinde birim testleri yürütmek," umursamama "durumuna ait oldukları için test etme zahmetidir. Bu daha ziyade değil: "Diğer işlevlerin her biri için alay oluşturmak," umursamıyorum "durumuna ait oldukları için test etme zahmetidir.
Mik378

@ Mik378 - evet, tam olarak bunu yapıyordum, sadece farklı bir şekilde ifade ettim. Bunu daha açık hale getirmek için cevabımı güncelledim.

Ama "koşu birimi testleri" terimini kafa karıştırıcı buluyorum. Bu, MusicCentre'ın ortak çalışanını birim test etmek üzere olduğu anlamına gelir ... oysa aslında OWN hizmetlerini birim test etmek için ortak çalışanını MOCKS. Bu arada, şimdi anlamını anlıyorum :)
Mik378

@ Mik378 - aynı şeyi söylüyoruz ve bunu yapmak için muhtemelen kesin terminolojiden daha azını kullanıyorum. Karışıklık için özür dileriz.

4

Bu, bu ilişkiyi destekleyen hizmetin başka bir yerde alakalı olup olmadığını görmeyi zorlaştırır ve bir dahaki sefere sınıfla çalıştığımda analizi tekrar yapmak zorunda kalacağım.

Bu konuda çok düşündükten sonra, bu teklifin olası bir yorumunu alıyorum:

Belirtilen "hizmet", "çizelgeleme olgusuna" karşılık gelir. Bu, "ScheduledDevice" adlı iyi adlandırılmış ve "bir role odaklanmış" arabirim ile ifade edilebilir veya herhangi bir arabirime bağlı olmayan somut bir yöntem uygulamasıyla örtük olarak ifade edilebilir.

Yukarıdaki örnekte, zamanlama adlı tam özellikli nesnenin tamamı tarafından ifade edilir CDPlayer. Böylece, hala MusicCentreve "çizelgeleme olgusu" arasında örtük bir ilişkiye yol açar .

Dolayısıyla, somut sınıflar enjekte edip üst düzey nesnelere alay edersek; Bunları test etmek istediğimizde, saklanan her bir somut nesneyi analiz etmek zorundayız. Aksine, HER ZAMAN arabirim üzerinden kodlanması, geliştiricinin üst düzey nesne tarafından ne tür bir ilişkinin sunulmak üzere olduğunu doğrudan anlayabilmesini ve böylece birim testini izole etmek için taklit edilmesi gereken özellikleri algılamasını sağlar.


Sanırım şimdi anladın. Maalesef, yorumunuzla ilgili bir bildirim almadım.
Steve Freeman

3

Burada demek istediğim hizmet CDPlayer.scheduleToStartAt () idi. MediaCentre bunu çağırır - çalışması için gereken ortak çalışan. MediaCentre test edilen nesnedir.

Fikir şu ki, bir uygulama sınıfına değil, sadece MediaCentre'ın neye bağlı olduğunu açıklarsam, bu bağımlılık rolüne bir isim verebilir ve onun hakkında konuşabilirim. MediaCentre'ın bilmesi gereken tek şey, ScheduledDevices ile görüşmesidir. Sistemin geri kalanı değiştikçe, özellikleri değişmedikçe MediaCentre'ı değiştirmem gerekmeyecek.

Bu yardımcı olur mu?


(bu harika makalenin yazarı :)) bu cümleyi yorumlamak istedim: "Bu, bu ilişkiyi destekleyen hizmetin başka bir yerde alakalı olup olmadığını görmek için zorlaştırıyor ve bir dahaki sefere çalıştığımda analizi tekrar yapmam gerekecek "derler. Ne tür bir analiz? Hangi nesnenin yönteminin ilişkiyi uygulayacağını tespit etme gerçeği, bu açıkça gizlendiğinden?
Mik378
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.