OS Exec
Bu bölümün bütün kodlarını burada bulabilirsiniz
os/exec.Command()kullanarak XML verisi üreten bir komut çalıştırıyorum. Bu komut,GetData()adlı bir fonksiyon içinde çalıştırılacak.
GetData()'yı test etmek için kendi oluşturduğum bir test verisine sahibim.
_test.go dosyamda TestGetData adında bir testim var ve bu test, GetData() fonksiyonunu çağırıyor, ancak bu fonksiyon os.exec kullanıyor. Bunun yerine test verilerimi kullanmasını istiyorum.
Bunu başarmanın iyi bir yolu nedir? GetData'yı çağırırken bir "test" bayrak moduna sahip olmalı mıyım, böylece GetData(mode string) gibi bir dosyayı okuyacak mı?
Bir kaç şey;
Bir şeyin test edilmesi zor olduğunda, bu genellikle endişelerin ayrılmasının pek doğru olmamasından kaynaklanır.
Kodunuza "test modları" eklemeyin, yerine Dependency Injection kullanın, böylelikle endişeleri ayırabilir ve kendi bağımlılıklarınızı modelleyebilirsiniz.
Kodun neye benzeyeceğini tahmin etmeye çalıştım:
type Payload struct {
Message string `xml:"message"`
}
func GetData() string {
cmd := exec.Command("cat", "msg.xml")
out, _ := cmd.StdoutPipe()
var payload Payload
decoder := xml.NewDecoder(out)
// these 3 can return errors but I'm ignoring for brevity
cmd.Start()
decoder.Decode(&payload)
cmd.Wait()
return strings.ToUpper(payload.Message)
}Sürece harici bir komut yürütmenize izin veren
exec.Commandı kullanır.Çıktıyı
cmd.StdoutPipeta yakalıyoruz ve bu bıze bırio.ReadCloserdöndürüyor (bu ileride önemli olacak).Kodun az çok geri kalan kısmı mükemmel dokümantasyondan kopyalanıp yapıştırılmıştır.
Stdout'tan herhangi bir çıktıyı
io.ReadCloseriçine alıyoruz ve komutubaşlatıyoruz, ardındanWaiti çağırarak tüm verilerin okunmasını bekliyoruz. Bu iki çağrı arasında verinin kodunu 'Payload' yapımızda çözüyoruz.
İşte msg.xml içinde bulunanlar:
Bunu uygulamalı olarak göstermek için basit bir test yazdım:
Test edilebilir kod
Test edilebilir kod ayrıştırılmış ve tek amaçlıdır. Bana, bu kod için iki ana endişe var gibi geliyor:
Ham XML verilerini alma
XML verilerinin kodunun çözülmesi ve iş mantığımızın uygulanması (bu senaryoda
<message>dakistrings.ToUpper)
İlk kısım sadece standart kütüphanedeki örneği kopyalıyor.
İkinci kısım iş mantığımızın oluştuğu yerdir ve koda bakarak mantığımızdaki "dikişin" nerede başladığını görebiliriz; io.ReadCloserımızı aldığımız yer burasıdır. Bu mevcut soyutlamayı endişeleri ayırmak ve kodumuzu test edilebilir hale getirmek için kullanabiliriz.
GetData ile ilgili sorun, iş mantığının XML alma araçlarıyla bağlantılı olmasıdır. Tasarımımızı daha iyi hale getirmek için onları ayırmamız gerekiyor
TestGetDatamız iki endişemiz arasındaki entegrasyon testimiz olarak hareket edebilir, bu yüzden çalışmaya devam ettiğinden emin olmak için onu elimizde tutacağız.
İşte yeni ayırılmış kod böyle gözüküyor:
Artık GetData girdisini yalnızca io.Readerdan aldığından onu test edilebilir hale getirdik ve artık verilerin nasıl alındığıyla ilgilenmiyoruz; insanlar bu işlevi io.Reader döndüren herhangi bir şeyle yeniden kullanabilirler (ki bu son derece yaygındır). Örneğin XML'i komut satırı yerine bir URL'den almaya başlayabiliriz.
İşte GetData için bir birim testi örneği.
Go testinde endişeleri ayırarak ve mevcut soyutlamaları kullanarak önemli iş mantığımızı kullanmak çocuk oyuncağıdır.
Bu sayfa @rasimthegrey tarafından çevrildi.
Last updated
Was this helpful?