2013-05-29 153 views
0

我試圖嘲笑一種方法,它編譯沒有錯誤,但當我運行一個測試奇怪的事情發生。其實方法犯規模擬也許我不明白不便...(犀牛嘲笑不嘲笑一種方法

這裏有一個代碼:

public class Robot 
{ .... 

    public virtual bool range(IObs ob, double range) 
    { 
     double dist = ob.distanceSq(this); 
     if (dist < range) 
      return true; 
     else 
      return false; 
    } 
} 

...

public interface IObs 
{ 
    double distanceSq(Robot r); 
} 

...

單元測試:

[TestClass] 
public class UnitTest1 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     MockRepository mocks = new MockRepository(); 
     IObs obstacleMock = mocks.CreateMock<IObs>(); 
     Robot r = new Robot(); 
     Expect.Call(obstacleMock.distanceSq(r)).IgnoreArguments() 
      .Constraints(Is.Anything()) 
      .Return(5.5); 
     Assert.IsTrue(r.range(obstacleMock, 0.5)); 
    } 
} 

I mock distanceSq() 。 當我調試我的測試時,我發現ob.distanceSq(this)爲0.0。 (不是1.5)。

怎麼了?

+0

你在這裏有很多問題,我猜。這就是說,當精度很重要時,使用'decimal'而不是'double';否則你會發現你期望'1.5',但你會繼續得到像'1.49999999'或'1.50000001'這樣的東西。 (http://stackoverflow.com/questions/1165761/decimal-vs-double-which-one-should-i-use-and-when) –

+0

@GrantWinney - 在這種情況下使用'deciaml'可能沒有用處 - double「對於大多數距離計算來說應該是足夠的了。 –

+0

@AlexeiLevenkov,我指的是一個'decimal'將會保留你存儲在其中的_exact_數字,而'double'則不太準確(你可以將1.5存儲在'double'中,然後當你去使用它的值爲1.5000000001)。 –

回答

0

您的代碼實際上並未使用嘲笑你創建的 - 因爲你可以改變ObstacleIObjs作爲range論證和比合格Obstacle新實例的模擬來代替:

public virtual bool range(IObjs ob, double range).... 
class Obstacle : IObjs ... 

Assert.IsTrue(r.range(obstacleMock, 0.5)); 
+0

我做了這個改變,但方法仍然沒有模擬。但是,現在,在調試器中,我得到0.0而不是0.0000000000000099999999999999984。 –

0

我會建議您升級RinoMocks版本到3.6並使用新的語法。

此外,如果您使用模擬IObs,您可能還會驗證distanceSq方法被調用。

我已經留在distanceSq方法出這個代碼的參數驗證,但你可以確保正確的機器人實例傳入。

單元測試仍將但是失敗,因爲5.5是更大比0.5

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Rhino.Mocks; 

namespace Rhino 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      var r = new Robot(); 
      var obstacleMock = MockRepository.GenerateMock<IObs>(); 
      obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Anything)).Return(5.5); 
      //use this line to ensure correct Robot is used as parameter 
      //obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Equal(r))).Return(5.5); 
      var result = r.range(obstacleMock, 0.5); 
      obstacleMock.VerifyAllExpectations(); 
      Assert.IsTrue(result); 
     } 
    } 

    public class Robot 
    { 
     public virtual bool range(IObs ob, double range) 
     { 
      return ob.ditanceSq(this) < range;   
     } 
    } 

    public interface IObs 
    { 
     double ditanceSq(Robot r); 
    } 
}