2013-05-29 33 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); 
    } 
}