2011-04-11 175 views
0

例如採取下面的類:如何使用moq設置受保護方法的模擬值?

class GameBoard  
{ 
    public double Evaluate(PieceType cpusPieceType) 
    { 
     ... 
     for (var i = 0; i < _tableRepository.Size; ++i) 
      for (var j = 0; j < _tableRepository.Size; ++j) 
       if (_tableRepository [i, j] != PieceType.Empty) 
       { 
        var isMax = _tableRepository [i, j] == cpusPieceType; 

        var value = EvaluatePosition (i, j, _tableRepository [i, j]); 
        ... 
       } 
     ... 
    } 

    protected virtual double EvaluatePosition (int row, int column, PieceType pieceType) 
    { ... } 
} 

我想編寫評估功能的測試,但是這又依賴於通過聲明保護EvaluatePosition函數返回的值。現在,我的想法是,我可以使用這樣一個類:

class XGameBoard : GameBoard 
{ 
    protected override double EvaluatePosition (int row, int column, PieceType pieceType) 
    { 
     // this will call EvaluatePosition_ShouldReturn which will be mocked and have a value previously set up 
     return EvaluatePosition_ShouldReturn (row, column, pieceType); 
    } 
    public virtual double EvaluatePosition_ShouldReturn (int row, int column, PieceType pieceType) 
    { 
     return base.EvaluatePosition (row, column, pieceType); 
    } 
} 

測試應該是這樣的:

_gameBoardMock = new Mock<XGameBoard>(...); 

for (var i = 4; i < _size - 4; i += 2) 
    for (var j = 4; j < _size - 4; j += 2) 
     _gameBoardMock.Setup (x => x.EvaluatePosition_ShouldReturn (i, j, PieceType.Cross)).Returns (1.0); 

var result = _gameBoardMock.Object.Evaluate (PieceType.Cross); 

的問題是,EvaluatePosition內部評估函數總是返回0,而不是被調用的overriden函數應該返回設置的值。

在此先感謝。

回答

0

我想澄清一點問題。情況是,Evaluate函數應該返回一個基於某些邏輯和EvaluatePosition函數的返回值的double值。基本上,Evaluate函數依賴於EvaluatePosition函數返回的值,但函數必須單獨測試,所以必須爲EvaluatePosition函數創建一個存根,並通過初始設置返回值來模擬返回值。我的方法似乎是使用所需要的僅僅是下面的語句:

_gameBoardMock.CallBase = true; 

因爲EvaluatePosition功能declated保護,它應該返回不能起訂量來設置的值,所以我創建了XGameBoard類該聲明EvaluatePosition_ShouldReturn功能是公共的和可用的起訂量和這樣我可以建立正常的EvaluatePosition函數返回值:

_gameBoardMock.Setup (x => x.EvaluatePosition_ShouldReturn (i, j, PieceType.Cross)).Returns (1.0); 

因爲EvaluatePosition功能在XGameBoard類,當這個功能重寫被調用它將調用EvaluatePo sition_ShouldReturn函數,其值由Moq設置,並返回指定的值。

我希望有些人可能會發現這種方法對單元測試很有用。快樂的編碼。

0

很難說什麼價值被返回,因爲你有...代替任何回報。從我可以看到,雖然你的生產代碼循環從0開始,並達到董事會的大小,而你的模擬設置目標具體組合。

如果你想所有的組合是設置然後就doon't在測試循環和簡單地做:

_gameBoardMock.Setup (x => x.EvaluatePosition_ShouldReturn (
     It.IsAny<int>(), 
     It.IsAny<int>(), 
     It.IsAny<PieceType>())).Returns (1.0); 

但是沒有看到你有什麼邏輯是如何圍繞一個值從Evaluate返回方法,那麼可能有其他原因。

另一種選擇是不使用最小起訂量。既然你有派生類,你可以簡單地改變受保護的方法來返回你的值。

protected override double EvaluatePosition (int row, int column, PieceType pieceType) 
{ 
    return 1.0; 
}