Исключения RhinoMocks при заглушении метода Equals - PullRequest
4 голосов
/ 11 сентября 2009

У меня проблема с настройкой теста для метода 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; }
}

Теперь я хочу, чтобы Equals of Hours: IHours проверял OpenAt и CloseAt IHours. Чтобы настроить это, я пытаюсь заглушить эти значения свойств и просто возвращаю 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 v3.5.0.1337 - NUnit.Framework v2.5.0.8332

У кого-нибудь есть идеи?

Ответы [ 2 ]

7 голосов
/ 11 сентября 2009

Да, это сложно - ошибка сумасшедшая, это не имеет никакого отношения к IAircraft. По сути, проблема в том, что интерфейс не является классом и, следовательно, не наследуется от объекта . Другими словами - closeAt не имеет метода Equals для удаления.

На самом деле, это, вероятно, немного языковая ошибка, которую вы даже можете явно вызывать 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);
}
0 голосов
/ 13 сентября 2009

Если я что-то упустил, Time of Day должен быть простым неизменным объектом. Так что я бы просто реализовал его как небольшой, проверенный класс значений. Тогда вы можете использовать реальный метод Equals.

...