代码之家  ›  专栏  ›  技术社区  ›  Tomas

当删除等于方法时,Rhinomock异常

  •  4
  • Tomas  · 技术社区  · 15 年前

    在对象上为equals方法设置测试时遇到问题。

    相关对象由此接口定义:

    public interface IHours {
        ITimeOfDay OpenAt { get; set; }
        ITimeOfDay CloseAt { get; set; }
        DateTime ValidFrom { get; set; }
        DateTime ValidTo { get; set; }
        bool isCovered(DateTime time);
    }
    

    它包含对ITimeOfDay的引用,定义如下:

    public interface ITimeOfDay {
        DateTime Time { get; set; }
        int Hour { get; }
        int Minute { get; }
        int Second { get; }
    }
    

    现在,我要的是时间的等量:我要检查打开和关闭的时间。为了设置这个,我尝试将那些属性值存根掉,并根据我的特定测试需要返回true和false。

        [SetUp]
        public virtual void SetUp() {
            mocks = new MockRepository();
    
            defaultHours = getHours();
            otherHours = getHours();
    
        }
    
        [TearDown]
        public virtual void TearDown() {
            mocks.ReplayAll();
            mocks.VerifyAll();
        }
    
        [Test(Description = "Equals on two Hours should regard the fields")]
        public void Equals_TwoValueEqualledObjects_Equal() {
            var openAt = mocks.Stub<ITimeOfDay>();
            var closeAt = mocks.Stub<ITimeOfDay>();
    
            closeAt                                   //this is line 66, referenced in the error stacktrace
                .Stub(o => o.Equals(null))
                .IgnoreArguments()
                .Return(true);
    
            openAt
                .Stub(c => c.Equals(null))
                .IgnoreArguments()
                .Return(true);
            mocks.ReplayAll();
    
            defaultHours.OpenAt = openAt;
            otherHours.OpenAt = openAt;
    
            defaultHours.CloseAt = closeAt;
            defaultHours.CloseAt = closeAt;
    
            Assert.That(defaultHours, Is.EqualTo(otherHours));
            Assert.That(defaultHours.GetHashCode(), Is.EqualTo(otherHours.GetHashCode()));
        }
    

    但当我运行它时,我会得到这个神秘的错误:

    System.InvalidOperationException: Type 'System.Boolean' doesn't match the return type   'System.Collections.Generic.IList`1[NOIS.Model.Interfaces.IAircraft]' for method 'IAircraftType.get_Aircrafts();'
    at Rhino.Mocks.Expectations.AbstractExpectation.AssertTypesMatches(Object value)
    at Rhino.Mocks.Expectations.AbstractExpectation.set_ReturnValue(Object value)
    at Rhino.Mocks.Impl.MethodOptions`1.Return(T objToReturn)
    at Nois.Test.Model.Entities.HoursTest.Equals_TwoValueEqualledObjects_Equal() in HoursTest.cs: line 66 
    

    IAircrafttype接口是同一命名空间的一部分,但它在测试、接口或实现类中的任何位置都不会被引用。我不明白它为什么会干扰。据我所知,它没有任何参考。

    我正在使用 -Rhino.Mocks第3.5.0.1337版 -nunit.framework 2.5.0.8332版

    有人知道吗?

    2 回复  |  直到 11 年前
        1
  •  7
  •   George Mauer    15 年前

    是的,这很复杂-错误是疯狂的,这与我的飞机无关。本质上问题是 接口不是类,因此不从对象继承 . 换句话说,closeAt没有一个等量的方法来终止。

    实际上,它可能是一个语言错误,您甚至可以在对象强制转换到接口上显式调用equals()。

    有两种方法可以解决这个问题

    1. 不要模拟接口,模拟实现mocks.stub()-这确实有一个虚拟的equals方法,因此您的代码可以工作。
    2. 更好的是,在接口中添加一个equals方法。一旦您这样做了,您将能够重写它,并且由于所有类都继承自对象,所以您将不必显式地实现它(除非您愿意)。

    换句话说

    var intrface = MockRepository.GenerateStub<IInterface>();
    intrface.Stub(x => x.Equals(null)).IgnoreArguments().Return(true); 
    

    休息时

    public interface IInterface {
    }
    

    但工作时

    public interface IInterface {
      bool Equals(object obj);
    }
    
        2
  •  0
  •   Steve Freeman    15 年前

    除非我错过了什么,否则一天中的时间应该是一个简单不变的对象。所以我将它作为一个小的、经过测试的值类来实现。然后可以使用real equals方法。