Domanda

Ho riscontrato un problema durante l'impostazione di un test per un metodo uguale su un oggetto.

L'oggetto in questione è definito da questa interfaccia:

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

e contiene riferimenti a ITimeOfDay definito come:

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

Ora voglio che Equals of the Hours: IHours controlli OpenAt e CloseAt IHours. Per impostare questo, provo a cancellare quei valori di proprietà, e restituisco vero e falso a seconda di ciò che il mio test particolare ha bisogno di essere.

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

Ma ottengo questo errore criptico quando lo eseguo:

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 

L'interfaccia IAircraftType fa parte dello stesso spazio dei nomi, ma in nessun punto del test, dell'interfaccia o della classe di implementazione viene fatto riferimento. Non capisco perché interferisca. Non vi è alcun riferimento ad esso per quanto posso raccogliere.

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

Qualcuno ha qualche idea?

È stato utile?

Soluzione

Sì, questo è complicato - l'errore è pazzo, questo non ha nulla a che fare con IAircraft. Essenzialmente il problema è che un'interfaccia non è una classe e quindi non eredita dall'oggetto . In altre parole, closeAt non ha un metodo Equals per stub.

È un dato di fatto, probabilmente è un po 'un linguaggio flub che puoi persino chiamare Equals () esplicitamente su un oggetto proiettato su un'interfaccia.

Quindi due modi per risolvere questo problema

  1. Non deridere l'interfaccia, deridere l'implementazione mocks.Stub () - questo ha un metodo uguale che è virtuale, quindi il tuo codice funzionerà.
  2. Ancora meglio, aggiungi un metodo Equals alla tua interfaccia. Una volta fatto, sarai in grado di sovrascriverlo e poiché tutte le classi ereditano dall'oggetto non dovrai implementarlo in modo esplicito (a meno che tu non voglia).

In altre parole

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

Si interrompe quando

public interface IInterface {
}

ma funziona quando

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

Altri suggerimenti

A meno che non mi manchi qualcosa, Time of Day dovrebbe essere un semplice oggetto immutabile. Quindi lo implementerei solo come una piccola classe di valore testata. Quindi puoi usare il vero metodo Equals.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top