Kodu dahili yapma, ancak diğer projelerden birim testi için kullanılabilir


Yanıtlar:


205

.NET kullanıyorsanız, InternalsVisibleTo derleme özniteliği "arkadaş" derlemeleri oluşturmanıza olanak tanır. Bunlar, diğer derlemenin iç sınıflarına ve üyelerine erişmesine izin verilen, kesin olarak adlandırılmış belirli derlemelerdir.

Bu, ilgili tertibatları sıkıca birleştirdiği için dikkatli kullanılmalıdır. InternalsVisibleTo için yaygın bir kullanım, birim test projeleri içindir. Yukarıda belirtilen nedenden ötürü, muhtemelen gerçek uygulama düzeneklerinizde kullanmak için iyi bir seçim değildir.

Misal:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{

23
Özniteliğin etrafına bir #if DEBUG koymanızı ve ardından hata ayıklamada birim testi yapmanızı öneririm. Bu şekilde, özelliğin sürüm kodunda ayarlanmadığından emin olursunuz.
steve cook

Bu sadece bir fikir, bilmiyorum .... Şuna ne dersiniz: # Genel sınıfta hata ayıklama IniReader #else dahili sınıf IniReader #endif Muhtemelen önerilmez? Neden?
jmelhus

4
Peki, neden testleri derlemelerde hata ayıklamak için sınırlandıralım?
Marco Mp

2
Ayrıca, sadece bir nitpick, "arkadaş" meclislerinin güçlü bir şekilde adlandırılmasına gerek yoktur (kişisel zevklerim aksini söylese de, zorunlu olmasa bile iyi bir uygulama olabilir).
Marco Mp

9
Katılmıyorum. Çok ince bir genel API ile karmaşık bir bileşen oluşturuyorsam, yalnızca genel API aracılığıyla test etmek pratik değildir ve gerçekçi değildir. Sonunda bakımsız bir çamur topuyla karşılaşacaksınız. Bunun yerine, iç birimleri dikkatlice tanımlar ve ayrı ayrı test ederdim. Jeremy D. Miller'ın oldukça sık söylediği gibi: "Büyük test etmeden önce küçük test edin".
Dennis Doomen

6

Dahili bir sınıfsa, tek başına kullanılmamalıdır. Bu nedenle, bu nesneyi dahili olarak kullanan başka bir sınıfı test etmek dışında gerçekten test etmemelisiniz.

Bir sınıfın özel üyelerini test etmemeniz gerektiği gibi, bir DLL'nin dahili sınıflarını da test etmemelisiniz. Bu sınıflar, kamuya açık bazı sınıfların uygulama ayrıntılarıdır ve bu nedenle diğer birim testleri aracılığıyla iyi bir şekilde uygulanmalıdır.

Buradaki fikir, yalnızca bir sınıfın davranışını test etmek istemenizdir, çünkü dahili uygulama ayrıntılarını test ederseniz, testleriniz kırılgan olacaktır. Tüm testlerinizi bozmadan herhangi bir sınıfın uygulama detaylarını değiştirebilmelisiniz.

O sınıfı gerçekten test etmeniz gerektiğini anlarsanız, o zaman ilk olarak o sınıfın neden dahili olduğunu yeniden incelemek isteyebilirsiniz.


2
Uygulama detayları, kapsamlı bir testin parçası olarak uygulanmalıdır. Özel değişkenlere bakmayın ... beklenen davranışı test edin. Test doğruysa .. tüm iç tesisat ve kablolar bunun bir parçası olarak test edilmelidir. Oy verildi.
Gishu

69
Bu sınıflar DLL içindeki diğer sınıflar için "genel" olduğundan ve sınıfın işlevselliğinin bağımsız olarak test edilmesi gerektiğinden buna kesinlikle katılmıyorum
leora

27
Ben de katılmıyorum. Birimler birimlerdir ve ayrı olarak test edilmelidirler.
Sentinel

5
Harika bir genel kural, ancak dogmatik olmayalım. Testler iki ana amaca hizmet eder: 1) Gerileme - bir şeyi bozmadığınızdan emin olun, 2) Geliştirme hızını artırmak. Her seferinde bir kod satırı yazmak istediğimde büyük bir hizmete dayanmam gerekirse, gelişimi engelleyeceğim. Karmaşık bir iç parçam varsa, tek başına geliştirmek ve test etmek istiyorum. Tersine, her şeyin tek başına test edilmesini istemiyorum (dolayısıyla regresyon testi değerini düşürmek veya test kodunu tekrarlamak), ancak bazı kodlar izolasyonu haklı çıkarır. Belki de anahtar, onu ayrı bir montaj yapmaktır.
Lee Jensen

2
Buradaki OP doğru. Testlerinizi dahili uygulamaya bağlıyorsunuz. Bu nedenle ekibiniz sonsuza kadar testleri ve korkunç alay kodlarını onarmak için bir köle olacaktır. Yalnızca genel API'leri test edin, paketlenmiş kitaplık API'leri veya ağa açık API'ler. Tüm kod, ön kapı üzerinden kullanılabilir olmalıdır. Test uygulaması, TDD'nin büyük ölçüde ölmesinin nedenidir, sistemin davranışlarını sağlamaya odaklanmak yerine tüm uygulamanın her sınıfını kelimenin tam anlamıyla test etmek sadece büyük bir PITA'dır. Sanırım "otoriter" kitaplar dahil neredeyse herkes bunu yanlış anladı veya açıklığa kavuşturmadı.
Luke Puplett

4

dokümantasyon amaçlı

alternatif olarak, Type.GetTypeyöntemi kullanarak dahili sınıfı başlatabilirsiniz

misal

//IServiceWrapper is public class which is 
//the same assembly with the internal class 
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
    .CreateInstance(type, new object[1] { /*constructor parameter*/ });

genel tip için aşağıdaki gibi farklı süreçler vardır:

var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
     .CreateInstance(genType, new object[1] { /*constructor parameter*/});

-5

Sınıflar hem halka açık hem de mühürlü olabilir.

Ama bunu yapma.

İç sınıfları yansıtmak için bir araç oluşturabilir ve yansıtma yoluyla her şeye erişen yeni bir sınıf ortaya koyabilirsiniz. MSTest bunu yapar.

Düzenleme: Yani, orijinal montajınıza -herhangi- test malzemesi eklemek istemiyorsanız; bu, üyeler özelse de işe yarar.


1
Bir dakika ne? Yapma diyorsun public sealed class? O mücevher için gerekçeniz nedir?
ezmek

@crush traumapony 2009 yılından beri giriş yapmadı.
Prof. Falken
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.