8

DDD, etki alanı nesnelerinin herhangi bir zamanda geçerli bir durumda olmasını önerir. Agrega kökleri, gerekli olan tüm parçalara sahip nesnelerin bir araya getirilmesi için geçerli bir durumda başlatılacak şekilde, değişmezleri ve Fabrikaları garanti etmekten sorumludur. Bununla birlikte, bu basit ve izole ünite testleri oluşturma görevini çok zorlaştırıyor gibi görünmektedir.Ünite testlerinizi nasıl basit ve izole tutmaya devam edersiniz ve DDD invaryantlarını garanti eder?

Kitap içeren bir Kitap Kitabımız olduğunu varsayalım. Bir Kitap sahiptir:

  • bir Yazar
  • bir Kategori
  • Kitapçılar bir liste

Bunlar gerekli özellikler kitabı bulabilirsiniz

  • : Bir kitap olan bir yazar olması, bir kitap ve en az bir kitapçıdan kitap satın alabilirsiniz. Oldukça karmaşık bir nesne olduğu için BookFactory olması muhtemeldir ve Fabrika, en azından belirtilen tüm nitelikler ile Kitabı başlatacaktır. Belki de Kitap kurucusunu özel (ve Fabrikada yuvalanmış) yaparız, böylece hiç kimse Fabrika dışındaki boş bir Kitabı başlatamaz.

    Şimdi, tüm Kitapları döndüren BookRepository'nin bir yöntemini test etmek istiyoruz. Yöntemin kitapları iade edip etmediğini test etmek için, bazı Kitapların Havuzda bulunduğu bir test bağlamı (AAA terimlerinde Düzenleme adımı) oluşturmamız gerekir. C#

    :

    [Test] 
    public void GetAllBooks_Returns_All_Books() 
    { 
        //Lengthy and messy Arrange section 
        BookRepository bookRepository = new BookRepository(); 
        Author evans = new Author("Evans", "Eric"); 
        BookCategory category = new BookCategory("Software Development"); 
        Address address = new Address("55 Plumtree Road"); 
        BookStore bookStore = BookStoreFactory.Create("The Plum Bookshop", address); 
        IList<BookStore> bookstores = new List<BookStore>() { bookStore }; 
        Book domainDrivenDesign = BookFactory.Create("Domain Driven Design", evans, category, bookstores); 
        Book otherBook = BookFactory.Create("other book", evans, category, bookstores); 
        bookRepository.Add(domainDrivenDesign); 
        bookRepository.Add(otherBook); 
    
        IList<Book> returnedBooks = bookRepository.GetAllBooks(); 
    
        Assert.AreEqual(2, returnedBooks.Count); 
        Assert.Contains(domainDrivenDesign, returnedBooks); 
        Assert.Contains(otherBook, returnedBooks); 
    } 
    

    elimizde yalnızca aracı Kitap Fabrikası, birim test şimdi kullanır ve Factory ve inderectly beri Kategori, Yazar ve Mağaza bağlıdır nesneleri oluşturmak için düşünüldüğünde Bir Kitap oluşturmak için bu nesnelere ihtiyacımız var ve test bağlamına yerleştirelim.

    Bu, bir Hizmet birimi sınamasında Hizmet’in arayacağı bir Deponun bağımlı olacağı şekilde bir bağımlılık olduğunu düşünür müsün?

    Basit bir şeyi test edebilmek için, tüm nesne kümesini yeniden oluşturmak zorunda kalmanın problemini nasıl çözersiniz? Bu bağımlılığı nasıl kıracak ve testimizde gerek duymadığımız tüm bu Kitap özelliklerinden nasıl kurtulacaksınız? Alay veya saplama kullanarak?

    Eğer veya tüketir test edilen nesne bir şey alay ne zaman görüşmelere aksine kullanırsınız sahte/koçanları ne tür bir Depo içeren şeyler, mock up olursa?

  • cevap

    4

    İki şey: testler içinde

    • kullanın sahte nesneler. Şu anda somut nesneler kullanıyorsunuz.

    • Karmaşık kurulum ile ilgili olarak, bazı noktalarda bazı geçerli kitaplara ihtiyacınız olacaktır. Her testten önce çalıştırmak için bu mantığı bir kurulum yöntemine çıkarın. Bu kurma yöntemini geçerli bir kitap koleksiyonu oluşturun ve benzerlerini yapın.

    "Nasıl sen kıracak nasıl? Bir basit bir şey test edebilmek amacıyla nesnelerin yeniden yaratmak bir bütün küme zorunda sorununu çözecek o bağımlılık ve 'un bu testimize gerek duymadığımız bu Book özniteliklerinden kurtulun mu?

    Sahte bir nesne bunu yapmanıza izin verir. Bir testin sadece geçerli bir yazarın bulunduğu bir kitaba ihtiyacı varsa, sahte nesneniz yazarın belirttiğini, diğer özniteliklerin varsayılan olacağını belirtir. Testiniz sadece geçerli bir yazarın umurunda olduğundan, diğer nitelikleri ayarlamanıza gerek yoktur.

    1

    Cevabınız için teşekkürler Finglas. Diğer testlerde alay kullanıyorum, ancak öncelikle test bağlamını kurmak için değil, etkileşim testi için kullanıyorum. Gerekli olan değerlere sahip bu tür bir boş nesnenin alay edilip edilemeyeceğinden ve bunları kullanmak için iyi bir fikir olup olmadığından emin değildim.

    Gerard Meszaros'un xunitpatterns.com adresindeki bir soruna ilginç ve oldukça yakın bir şey buldum. O olası çözümler Creation Methods veya Dummy Objects olan Irrelevant Information olarak uzun ve karmaşık bir test kurulumu sahip kod kokusu açıklar. Ben tamamen onun Kukla Nesne uygulamasında satmadım, çünkü benim örneğimde, çok basit bir yapıcı ile bir Taklit Kitabı uygulamak ve tüm Fabrika oluşturma mantığını atlamak için bir IBook arabirimine (ugh) sahip olmamı zorlayacağım.

    İzolasyon çerçevesinin oluşturduğu alayların ve oluşturma yöntemlerinin bir karışımının testlerimi netleştirmem ve basitleştirmemde yardımcı olabileceğini düşünüyorum.

    1

    Test Data Builder'u denemek isteyebilirsiniz. Nice post from Nat Pryce.

    Bu, alay rotasını gitmek istemiyorsanız yardımcı olabilir. Bütün bu çirkin fabrika yöntemlerini soyutlayabilir. Ayrıca üretim kodunuzda kullanılacak kurucuları zorlamaya çalışabilirsiniz.

    3

    Saf birim testleri için, alay ve kesikler kesinlikle çözümdür.

    • ayarladığınız yardımcı testi fabrikaları oluşturun: Eğer daha entegrasyon seviyesi testlerden sonra gidiyoruz ve mocks (veya koçanları veya ne olursa olsun) sorununuzu çözemesin Fakat, gerçekten iki makul seçenek var İhtiyacınız olan verileri toplayın. Bunlar muhtemelen sadece bir kitapçı oluşturmak değil, aynı zamanda makul bir kurgu kitaplarla doldurmak için testine özgü olacaktır. Böylece kurulum kodunuzu bir hatta ikiye sıkıştırır ve bunları başka testler için kullanırsınız. Bu kod, entegrasyon tipi testler için gerekli olan çeşitli senaryoları oluşturmak için büyüyebilir.

    • Bir kurulum oluşturun test fikstürleri. Bunlar, kullandığınız testler için küçük fakat kavramsal olarak eksiksiz veri setleridir. Bunlar genellikle bir tür serileştirilmiş formda (xml, csv, sql) depolanır ve her bir testin başında veritabanınıza yüklenir, böylece geçerli bir durumunuz olur. Onlar sadece statik dosyaları okuyarak çalışan genel bir fabrikadır.

    Fikstürü kullanırsanız, tekli veya çoklu fikstür yaklaşımını kullanabilirsiniz.Ünite testlerinizin çoğu için tek bir "kanonik" veri kümesinden kurtulabiliyorsanız, bu daha kolay olacak, ancak bazen anlaşılabilir olması için çok fazla kayda sahip bir veri kümesi oluşturuyor veya sadece menzili ifade etmiyor. Desteklemeniz gereken senaryolar. Bazı problemler, çok sayıda verinin kapsamlı bir şekilde test edilmesini gerektirir.

    1

    Belki de Kitap yapıcı özel yapacağız (ve iç içe Fabrikası ) kimse Factory hariç boş Kitabı örneğini böylece.

    Özel Book yapıcı, sorunlarınızın kaynağıdır.

    Book 'un yapıcısını dahili yaparsanız, fabrikanın iç içe olması gerekmez. Ardından, fabrikanın bir arabirimi (IBookFactory) gerçekleştirmesini sağlamakta özgürsünüz ve deponuza bir sahte kitap fabrikası enjekte edebilirsiniz.

    Gerçekten, fabrika uygulamaları örneklerini oluşturmak sadece kitap sağlamak fabrika ihtiyacı argümanları kabul edeceğini deposuna bir yöntem eklemek istiyorsanız: Ben birlikte DDD öğrenme başladı çünkü

    public class BookRepository { 
    
        public IBookFactory bookFactory; 
    
        public BookRepository(IBookFactory bookFactory) { 
         this.bookFactory = bookFactory; 
        } 
    
        // Abbreviated list of arguments 
        public void AddNew(string title, Author author, BookStore bookStore) { 
         this.Add(bookFactory.Create(title, author, bookStore)); 
        } 
    
    } 
    
    0

    II önyargılı CQRS ile yan. Ama doğru sınırları çizdiğinden emin değilim. Bir toplam yalnızca kendi değişmezleri hakkında bilmelidir. Bir kitabın yazarı olduğunu söylüyorsun. Evet, ancak kitabın yazarı üzerinde hiç değişmez. aşağıdaki gibi yüzden agrega kitap canlandırabiliyordu: Sorgu tarafı olsa bilgi kitabın her ikisi için ihtiyaç duyabileceğini olurdu

    public class Author 
    { 
        public string _name; 
    
        public Book(string name) 
        { 
         if(name==nullorEmpty) throw new ArgumentNullException(); 
    
         _name= name; 
        } 
    } 
    

    : Yazar yazarı üzerindeki bir değişmeyen sahiptir Oysa

    public class Book 
    { 
        public Guid _idAuthor; 
    
        public Book(Guid idAuthor) 
        { 
         if(idAuthor==guid.empty) throw new ArgumentNullException(); 
    
         _idAuthor = idAuthor; 
        } 
    } 
    

    ad ve yazar adı, ancak bu bir sorgudur ve IMO birim testi için uygun olmayabilir.

    Kitaplığınıza ekleyebilmeniz gerekiyorsa, yalnızca kendi yazarı "e" harfini yazdığında kitap, sonra tüm tartışma farklıdır, ancak anladığım kadarıyla, şu anda ona ihtiyacınız yok .

    Agregate Book'u oluştururken, birim sınaması daha kolay olur, çünkü yazma yönüne ve gerçek invaryantlara odaklanırsınız.

    İlgili konular