2013-12-23 57 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