2010-11-19 27 views
1

Testlerimin zamanını en çok geçirdiği, ancak bazen başarısız olduğu bir sorunum var. Ben bir iş parçacığı sorun olabileceğini düşünüyorum, ama sorunların nerede şanssız olduğunu bulmak için denemek ve kilitler vb. Doğru sözdizimini mi kullanıyorum? Bir süre sonra Rhino kullanmaya geri dönüyorum.Rhino Aaa AAA söz dizimi ve iş parçacığı güvenliği

Testlerimin dezenfekte edilmiş bir versiyonu. Dediğim gibi, 4 kez 3'ü çalışıyorlar, ama sonra bom.

[TestFixture] 
public class Tests 
{ 
    [Test] 
    public void ReprocessItems() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 

     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = false }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     // Act 
     presenter.ReprocessItems(); 

     // Assert 
     gateway.AssertWasCalled(o => o.ReprocessItem(1, presenter.ReprocessDone)); 
     gateway.AssertWasCalled(o => o.ReprocessItem(2, presenter.ReprocessDone)); 
    } 

    [Test] 
    public void ShowItemReferralCommentary() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 
     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     var view = MockRepository.GenerateStub<IView>(); 
     presenter.View = view; 

     gateway.Stub(x => x.RequestItemCommentary(1)).Return("This is some commentary"); 

     // Act 
     presenter.ShowItemReferralCommentary(); 

     // Assert 
     gateway.AssertWasCalled(o => o.RequestItemCommentary(1)); 

     view.AssertWasCalled(o => o.ShowMessageBox("This is some commentary", "Referral Commentary")); 
    } 

    [Test] 
    public void AcceptSelectedItems() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 
     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = true }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     // Act 
     presenter.AcceptSelectedItems(); 

     // Assert 
     gateway.AssertWasCalled(o => o.AcceptItem(3, presenter.AcceptCompleted)); 
     gateway.AssertWasCalled(o => o.AcceptItem(4, presenter.AcceptCompleted)); 
    } 
} 

DÜZENLEME: ** altında bir açıklama gereğince, geçici olarak bir Thread.Sleep (500) ekleyerek bu çözmüş; her iddiadan önce. Thread.Sleeps genellikle bir kod kokusu vardır ve ben onu kilitlemek istiyorum ama sloppy pragmatik olmaya çalışıyorum. Daha iyi bir yolunuz varsa lütfen bana bildirin.

+0

iş parçacığı yöntemleri nedir? – Simone

+0

ReprocessItem ve ReprocessDone gibi şeyler geri aramadır. –

cevap

5

Sorun şu ki test yöntemlerinin sonunda, iddiaları yerleştirdiğinizde, çocuklar işlerini yapıp yapamayacaklardı. Senin bakış açına göre, neredeyse rastgele.

Yapabildiğiniz şey, iş parçacıklı yöntemleri sınarken yaptığım şey, ManualResetEvent gibi bir eşitleme nesnesinin kullanılmasıdır. Sen başlayan test yöntemlerine de yanlış sıfırlayın: senin onaylama işlemi blok kodundan önce, Şimdi

Expect.Call(() => yourMock.yourMethod(whatever)).WhenCalled(x => wait.Set()); 

: En alay nesnesi test edilerek çağrıldığında

var wait = new ManualResetEvent(false); 

Sonra, onun durumunu ayarlamak

Assert(wait.WaitOne(timeoutOfYourChoice)); 

Bu, ikincil iş parçacığı çalışmalarını bitirmek için yeterli zaman bırakacaktır.

+0

Bunu yerleştirmeyi denedim, ama bir yerlerde bir şeyler kırılıyordu. Basit bir Thread.Sleep (500) 'i koymadan önce koyarsam, işe yarıyor. İdeal değil şu an için yeterince iyi. Bunu araştıracağım. ManualResetEvent bir kazanan olabilir. Bahşiş için teşekkürler. –

İlgili konular