2013-12-23 51 views
0

我想測試一個永久運行的遊戲循環,直到用戶退出或死亡,然後顯示一條消息。在TestFixtureSetup中創建線程會導致測試隨機失敗

事情是這樣的:

[TestFixtureSetUp] 
    public void SetupMethods() 
    { 
     _input = new Mock<IInput>(); 
     _input.SetupProperty(i => i.QuitKey, 'q'); 
     _messenger = new Mock<IMessenger>(); 
     _grid = new Mock<IGrid>(); 
     _clock = new Mock<IClock>(); 
     _game = new Game(_input.Object, _messenger.Object, _grid.Object, _clock.Object); 
    } 

    [Test] 
    public void should_loop_until_player_quits_then_show_confirmation() 
    { 
     _input.Setup(g => g.ReadKey()).Returns(_input.Object.QuitKey); 

     _messenger.Verify(m => m.SendMessage("Are you sure?")); 
    } 

    [Test] 
    public void should_loop_until_player_dies_then_show_game_over_message() 
    { 
     _game.IsGameOver = true; 

     _messenger.Verify(m => m.SendMessage("Game Over")); 
    } 

Game類裏面我有

public void GameLoop() 
    { 
     //gets player input 
     while (ReadKey() != _input.QuitKey && !IsGameOver) 
     { 
      //waits for clock 
      if (_clock.TimeElapsed % 1000 == 0) 
      { 
       //logic 
      }    
     } 

     if (IsGameOver) 
     { 
      _messenger.SendMessage("Game Over"); 
     } 
     else 
     { 
      _messenger.SendMessage("Are you sure?"); 
     } 
    } 

,使循環運行,我發現創建一個單獨的線程來它的工作原理,並沒有掛考試。但是,當我把新的線程代碼放入安裝程序時,如果我做了Test All(我有大約5或6),測試會隨機失敗。如果我分別進行每項測試,那很好。

[SetUp] 
    public void SetupTest() 
    { 
     new Thread(() => 
     { 
      Thread.CurrentThread.IsBackground = true; 
      _game.GameLoop(); 
     }).Start(); 
    } 

我在做什麼錯?因爲他們

  • 以隨機順序
  • 在測試中,你設置各種返回值在你的嘲弄運行

結果是

+0

你爲什麼在測試中這樣做? 「...直到用戶退出或死亡...」 - 如果您想讓用戶運行遊戲,請創建一個應用程序。 – adrianbanks

+0

不知道我是否理解這個問題,而且我更像是一個練習TDD的練習,而不是真正的應用。我對它仍然很陌生。 – happygilmore

+0

@adrianbanks看問題http://stackoverflow.com/a/5717938/1821057你會看到我最初的嘗試。 – happygilmore

回答

0

你的測試是不確定的:你永遠不會完全知道你的遊戲循環看到了什麼值。

爲了克服這一點,你必須設置你所有的嘲笑重新對每個測試的基礎上(即在SetUp,而不是在TestFixtureSetUp),因爲,據我所知,起訂量並沒有像一個Clear()方法爲嘲笑。

編輯
此外,您必須確保您的變量正確傳遞給線程。試試這個:

[SetUp] 
public void SetupTest() 
{ 
    _input = new Mock<IInput>(); 
    _input.SetupProperty(i => i.QuitKey, 'q'); 
    _messenger = new Mock<IMessenger>(); 
    _grid = new Mock<IGrid>(); 
    _clock = new Mock<IClock>(); 

    new Thread(() => 
    { 
     Thread.CurrentThread.IsBackground = true; 

     IInput input = _input.Object; 
     IMessenger messenger = _messenger.Object; 
     IGrid grid = _grid.Object; 
     IClock clock = _clock.Object; 

     _game = new Game(input, messenger, grid, clock); 
     _game.GameLoop(); 
    }).Start(); 
} 
+0

我試着在testfixture和setup中創建線程,同樣的問題。 – happygilmore

+0

我沒有說'線程創建',但'模擬創建和設置'... –

+0

沒有線程創建我的測試工作正常。不知道爲什麼你認爲他們是在隨機順序,因爲它是。 – happygilmore