Pregunta

Tengo un problema al configurar una prueba para un método Equals en un objeto.

El objeto en cuestión está definido por esta interfaz:

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

y contiene referencias a ITimeOfDay definidas como:

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

Ahora quiero los equivalentes a las horas: IHours para verificar OpenAt y CloseAt IHours. Para configurar esto, trato de eliminar esos valores de propiedad, y solo devuelvo verdadero y falso dependiendo de lo que mi prueba particular necesita que sean.

    [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()));
    }

Pero recibo este error críptico cuando lo ejecuto:

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 

La interfaz IAircraftType es parte del mismo espacio de nombres, pero no se hace referencia en ninguna parte de la prueba, la interfaz o la clase de implementación. No entiendo por qué interfiere. No hay ninguna referencia a él en la medida en que puedo recopilar.

estoy usando - Rhino.Mocks v3.5.0.1337 - NUnit.Framework v2.5.0.8332

¿Alguien tiene alguna idea?

¿Fue útil?

Solución

Sí, esto es complicado, el error es una locura, esto no tiene nada que ver con IAircraft. Esencialmente, el problema es que una interfaz no es una clase y, por lo tanto, no se hereda de un objeto . En otras palabras, closeAt no tiene un método Equals para apagar.

De hecho, es probable que sea un poco de un error de idioma que incluso puedes llamar a Equals () explícitamente en un objeto convertido a una interfaz.

Dos formas de solucionar esto entonces

  1. No se burle de la interfaz, se burla de los simulacros de implementación. Stub (): tiene un método igual que es virtual para que su código funcione.
  2. Aún mejor, agregue un método Equals a su interfaz. Una vez que lo haga, podrá anularlo y, como todas las clases heredan del objeto, no tendrá que implementarlo de forma explícita (a menos que quiera).

En otras palabras

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

Se rompe cuando

public interface IInterface {
}

pero funciona cuando

public interface IInterface {
  bool Equals(object obj);
}

Otros consejos

A menos que me esté perdiendo algo, la Hora del día debería ser un objeto simple e inmutable. Así que lo implementaría como una clase de valor pequeña y probada. Luego puedes usar el método de los reales iguales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top