2010-11-19 4 views
1

내 테스트에서 번을 가장 많이 통과하지만 가끔에 문제가있는 경우가 있습니다. 나는 그것이 쓰레딩 문제일지도 모른다라고 생각한다. 그러나 나는 자물쇠와 실험을했다. 그리고 문제가 아무런 운이없는 곳이라도 발견하려고 노력한다. 올바른 구문을 사용하고 있습니까? 잠시 후에 Rhino를 사용하게되었습니다.Rhino Mocks AAA 구문 및 스레드 안전

내 테스트 결과는 다음과 같습니다. 내가 말했듯이, 그들은 4 시간 중 3 번을 일하지만, 그 다음에 붐을 일으킨다.

[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)); 
    } 
} 

편집 : ** 아래의 코멘트 당, 나는 일시적으로 Thread.sleep를 (500)를 추가하여이 문제를 해결했다; 각 주장 앞에. Thread.Sleeps는 일반적으로 코드 냄새이며 잠글 때 사용하고 싶습니다. 은 실용적이 아닙니다. 실용적입니다. 더 좋은 방법이 있으면 알려주세요.

+0

스레드 메소드는 무엇입니까? – Simone

+0

ReprocessItem 및 ReprocessDone과 같은 것은 콜백입니다. –

답변

5

문제는 아이들 스레드가 작업을 수행 할 수있는 동안 테스트 메소드가 끝날 때, 어설 션을 배치 할 수 있다는 것입니다. 당신의 관점에서, 그것은 거의 무작위입니다.

내가 할 수있는 일은 스레드 메소드를 테스트 할 때 ManualResetEvent와 같은 동기화 객체를 사용하는 것입니다. 당신은 시작하는 시험 방법에 false로 재설정 : 당신의 주장 블록 코드 앞에 지금

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

: 당신의 모의는 개체가 테스트되고 의해 호출 될 때

var wait = new ManualResetEvent(false); 

그런 다음, 당신은 그것의 상태를 설정 다음과 같이 작성하십시오.

Assert(wait.WaitOne(timeoutOfYourChoice)); 

이렇게하면 보조 스레드가 작업을 완료 할 수있는 충분한 시간을 남겨 둡니다.

+0

나는 이것을 넣으려고했으나, 어딘가에서 무언가가 깨지고있었습니다. 내가 단언하기 전에 간단한 Thread.Sleep (500)을 넣으면 작동한다. 아직 이상적이지는 않다. 나는 이것을 연구 할 것이다. ManualResetEvent가 승자가 될 수 있습니다. 팁 고마워. –