2010-07-02 15 views
6

Aşağıdakileri içeren bir sınıf A:Bir MEF İthalat Mı?

public class A { 
    [Import(typeof(IMyService)] 
    public IMyService MyService { get; set; } 

    public A() { 
     CompositionInitializer.SatisfyImports(this); 
    } 

    public void DoWork() { 
     //Blah 
     MyService.DoIt(); 
     //Blah 
    } 
} 

Ve bunu sınamak için bir Test (ayrı ayrı Dll - açık olarak)

[TestMethod] 
public void TestDoWork() { 
    //Blah 
    DoWork(); 
    //Assert assert 
} 

Bu, 'MyService' çağırma girişiminde başarısız olduğunda başarısız olur. Daha sonra denedim:

'MyService' ile bildirildi:

[Export(typeof(IMyService))] 
public IMyService MyService { get; set; } 

Ama yine de neşe yok, bir şeyi özlüyorum - bu mümkün mü?

SL3, MEF Önizleme 9 ve MOQ kullanıyorum.

Herhangi bir yardım beğeni topladı!

Şerefe

Chris

cevap

4

Sınıfınız gibi görünmelidir

[TestMethod] 
public void DoWork_invokes_IMyService_DoIt() 
{ 
    // arrange mock and system under test 
    var myService = new Mock<IMyService>(); 
    var a = new A(myService.Object); 

    // act  
    a.DoWork(); 

    // assert that DoIt() was invoked 
    myService.Verify(x => x.DoIt()); 
} 

MEF birim testlerinde önemli olmamalı kullanmak gerçeği. MEF sadece birçok bileşenin kablolanması sırasında devreye girer; bu, bir birim testinde gerçekleşen şeyin tam tersidir. Bir birim testi, tanım olarak bir bileşenin tanımlanmasıdır.

Edit: Eğer mülk enjeksiyonu tercih ederseniz, o zaman sınıf artık şöyle görünmelidir bir kurucu ve birim test düzenlemek kısmını ihtiyacı yoktur: Sen ateş olmamalıdır

var myService = new Mock<IMyService>(); 
    var a = new A(); 
    a.MyService = myService.Object; 
+0

Tamam, ancak neden kurucu ithalatçıyı kullanmam gerekiyor, gerçek uygulamada mülk gayet iyi çalışıyor, muhtemelen bu tür ithal mallarla dalga geçebilecek bir yol var mı? –

+1

@Chris: MEF, mülk enjeksiyonunu teşvik etse de, inşaat enjeksiyonunu tercih ederim, çünkü derleyici, eksik bağımlılıkları olan nesneler oluşturmanızı engeller. Ayrıca bağımlılık alanlarını okuyup hazırlamanıza izin verir, böylece bir bağımlılık değiştirilirse ne olacağını düşünmek zorunda kalmazsınız. –

+0

Bu yöntemi tercih ettim, şahsen ben mülk enjeksiyonu ile alay yapıp yapamayacağınızı bilmek isterim, ancak bu, sahip olduğum sorunu düzeltmeye yardımcı olur. Şerefe. –

1

, aslında eklemiş bileşimi kabına o? Aksi takdirde, kompozisyona katılmaz. kaba bir alay nesnesi eklemek için, aşağıdakileri yapın:

container.ComposeExportedValue<IMyService>(mock.Object); 

Ya da sadece: Bunu yapmak

container.ComposeExportedValue(mock.Object); // type inference. 

Eğer A'nın içinde oluşan edilecek A'nın bir örneği bunu sağlayacak oluşturmadan önce örneği.

public class A 
{ 
    private readonly IMyService _myService; 

    [ImportingConstructor] 
    public A(IMyService myService) 
    { 
     _myService = myService; 
    } 

    public void DoWork() { 
     //Blah 
     _myService.DoIt(); 
     //Blah 
    } 
} 

Ve test aşağıdaki gibi görünmelidir:

+0

Ben çalışmak için almak için bir kaba somut uygulama eklemenize gerek yoktur. Ama senin amacını görüyorum. Kapsayıcıyı nerede görüyorsunuz? –

0

birim testlerinde MEF'yi yükseltin. Kompozisyon, bir IoC konteynerine benzemeyen, ünite testinin kapsamının ötesindedir. elle

Insted, gerekli enjekte edilmelidir bağımlılıkları:

[TestClass] 
public class ATest { 
    Mock<IMyService> myService ; 
    [TestInitialize] 
    public void InitialiseClass() { 
    myService = new Mock<IMyService>(); 
    } 

    [TestMethod] 
    public void DoWorkShouldCallDoIt { 
    A a = new A(); 
    a.MyService = myService.Object; 
    a.DoWork(); 
    myService.Verify(m=>m.DoIt(), Times.Once()); 
    } 
}