2012-03-12 12 views
5

Ho una classe che implementa ICollection<SomeConcreteClass>. I vincoli delle collezioni NUnit non lo riconoscono come una collezione.Cosa rende una classe una collezione in base ai vincoli della raccolta NUnit?

ad es. Assert.That(sut, Has.No.Member(someObjectOfTypeSomeConcreteClass)); tiri System.ArgumentException : The actual value must be a collection

e Assert.That(sut, Is.Empty); fallisce con vuoto sut.

Quindi quando è una raccolta una raccolta (secondo NUnit)?

dello stack:

System.ArgumentException : The actual value must be a collection Parametername: actual 
at NUnit.Framework.Constraints.CollectionConstraint.Matches(Object actual) 
at NUnit.Framework.Constraints.NotConstraint.Matches(Object actual) 
    MyTestFile.cs(36,0): at MyAssembly.MyTestFixture.MyTestMethod() 

problemi di cui sopra si è verificato con NUnit 2.4.3.0. L'ho appena provato con 2.6. Is.Empty funziona ora, ma Has.No.Member non riesce ancora. Non chiama nemmeno Equals() o operator ==(). Come confronta gli elementi della collezione? RhinoMocks Arg<MyCollection>.List.Count(Is.Equal(1)) ora non funziona.

Conclusione:
Con NUnit 2.4 della collezione vincoli richiedono attuazione ICollection non generico per la raccolta di essere riconosciuto come un insieme (che risponde alla domanda originale). L'uguaglianza IEnumerable funziona come previsto.

Con NUnit 2.6 (e possibilmente 3,0) l'uguaglianza di IEnumerable s viene controllata dagli elementi corrispondenti anche se Equals viene sovrascritto. Ecco perché il vincolo di appartenenza non funziona se gli elementi sono IEnumerable s stessi. Questo è un problema noto (https://bugs.launchpad.net/nunit-3.0/+bug/646786).

Per i dettagli vedere la mia risposta.

+0

potete inserire la piena pila di l'eccezione generata? –

risposta

1

Penso di aver capito.

NUnit 2.4.3.0 tenta di trasmettere a non generico ICollection che non ho implementato. Funziona ora con 2.4.

In NUnit 2.6.0.12051 c'è un NUnitEqualityComparer che fa questo:

if (x is IEnumerable && y is IEnumerable && !(x is string && y is string)) 
    return EnumerablesEqual((IEnumerable)x, (IEnumerable)y, ref tolerance); 

miei membri di raccolta sono IEnumerable e in caso di test sono tutte vuote. Ecco perché il vincolo ritiene che tutte le istanze siano uguali. Ma loro non lo sono. Il NUnitEqualityComparer presuppone che una classe abbia membri (IEnumerable) o che abbia il proprio stato. La mia classe membro della raccolta (chiamata SomeConcreteClass nella domanda) è sia enumerabile che ha anche altro stato, ad es. una proprietà Name. A causa del funzionamento di NUnitEqualityComparer, lo stato aggiuntivo non viene confrontato e gli oggetti vuoti con diverso stato aggiuntivo sono erroneamente ritenuti uguali.

Ne parlerò con la mailing list NUnit e riferirò qui.

Edit:

Questo comportamento è noto: https://bugs.launchpad.net/nunit-3.0/+bug/646786

1

Vedi qui http://www.nunit.org/index.php?p=collectionConstraints&r=2.5,

Per i riferimenti, Has.Member utilizza l'uguaglianza oggetto per trovare un membro in una collezione . Per verificare se un oggetto è uguale a un oggetto della raccolta, utilizzare Has.Some.EqualTo (...).

quindi suppongo che non si dispone di .equals (SomeConcreteClass) implementato, o la raccolta dovrebbe essere IEnumerable.

+0

Voglio affermare che la raccolta NON contiene l'oggetto dato. – EricSchaefer

+0

... e SomeConcreteClass implementa Uguale – EricSchaefer

+0

Quindi, è un'altra opzione - IEnumerable, anche @ Daniel Rose afferma che – Anton

2

Dopo aver esaminato il codice sorgente di NUnit 2.5.10: Il vincolo innesca prima la raccolta data al numero non generico IEnumerable.

MODIFICA: Quindi esegue un foreach() sopra la raccolta e confronta gli elementi. Quindi AFAICT dovrebbe funzionare.

Quale versione di NUnit stai usando?

+0

ICollection eredita sia IEnumerable e IEnumerable EricSchaefer

+0

il che significa che la mia classe implementa sia la variante generica e non generica ... – EricSchaefer

+0

@EricSchaefer Hai ragione. Ho corretto la risposta. –

Problemi correlati