2010-07-12 20 views
14

Sono nuovo per il derisione e sto riscontrando difficoltà a risolvere un problema con UnitTesting.Come posso utilizzare Rhino Mocks per verificare quali valori sono stati passati a un metodo

Dire che ho questo codice:

public class myClass{ 

    private IDoStuff _doer; 

    public myClass(IDoStuff doer){ 
     _doer = doer; 
    } 

    public void Go(SomeClass object){ 

     //do some crazy stuff to the object 

     _doer.DoStuff(object) //this method is void too 
    } 
} 

Ok, quindi voglio unit test il metodo Go. Non mi interessa cosa fa l'oggetto _doer all'oggetto una volta ottenuto.

TUTTAVIA, desidero controllare cosa ha ricevuto l'oggetto _doer.

in pseudo-codice che voglio raggiungere questo:

[Test] 
public void MyTest() 
{ 
    IDoStuff doer = Mocker.Mock<IDoStuff>(); 
    Guid id = Guid.NewGuid(); 

    //test Go method 
    new MyClass(doer).Go(new SomeClass(){id = id}); 

    Assert.AreEqual(id,MockingFramework.Method(DoStuff).GetReceived<SomeClass>().id); 
} 

Questo è possibile utilizzando Rhino, e se sì, come faccio a raggiungerlo?

applausi

risposta

21

Con la nuova sintassi Disponi/Act/Assert:

[Test] 
public void MyTest() 
{ 
    // arrange 
    IDoStuff doer = MockRepository.GenerateStub<IDoStuff>(); 
    MyClass myClass = new Myclass(doer); 
    Guid id = Guid.NewGuid(); 

    // act 
    myClass.Go(new SomeClass(){id = id}); 

    // assert 
    doer.AssertWasCalled(x => x.DoStuff(
     Arg<Someclass>.Matches(y => y.id == id))); 
} 
4

Penso che quello che hai è buono, quindi sarebbe:

IDoStuff doer = MockRepository.GenerateMock<IDoStuff>(); 

poi istituito l'aspettativa tramite:

doer.Expect(() => DoStuff(id)); 

poi alla fine:

doer.VerifyAllExpectations(); 

MODIFICATO da Lee's risposte a notare che si può anche fare cose come:

doer.Expect(d => d.DoStuff(Arg<int>.Is.GreaterThan(5)) 

o

doer.Expect(d => d.DoStuff(Arg<CustomObject>.Matches(x => x.CustomProperty == "Beef"))); 

o prove simili quando non si desidera confronti di riferimento precisi utilizzando gli oggetti Arg e Arg.

1

Se si vuole solo provare che l'istanza MyClass passa il suo parametro di doer.Go allora si può solo configurare un'aspettativa:

SomeClass obj = new SomeClass { id = id }; 

doer.Expect(d => d.DoStuff(obj)); 

//test go method 
new MyClass(doer).Go(obj); 

doer.VerifyAllExpectations(); 

Tuttavia, se si desidera verificare che passi qualche oggetto possibilmente diverso con un po ' particolare valore di una proprietà, quindi è possibile utilizzare un vincolo:

doer.Expect(d => d.DoStuff(null)) 
    .IgnoreArguments() 
    .Constraints(Property.Value("Id", expectedId)); 
7

Tutte queste risposte offrono vari modi per fare ciò che si desidera e tutti funzionano. C'è una cosa in più di cui essere a conoscenza. Se è necessario ottenere veramente un "livello basso" e verificare gli argomenti passati a qualsiasi metodo stubbed/mocked, è possibile utilizzare GetArgumentsForCallsMadeOn.

È un po 'caotico in quanto restituisce oggetto [] []. Si utilizza in questo modo (supponendo che si spense stubber.InsertData accettare null):

var args = stubber.GetArgumentsForCallsMadeOn(s => s.InsertData(null)); 

args [0] è un array di parametri passati al InsertData la prima volta è stato chiamato.

args [1] è un array di parametri passati a InsertData la seconda volta che è stato chiamato.

ecc ...

Quindi, se si voleva vedere il valore intero passato come secondo parametro la prima chiamata di un metodo si potrebbe:

var check = (int) args[0][1]; 

Anche in questo caso, mi consiglia uno dei metodi precedenti, ma questo è disponibile se hai bisogno di essere veramente giù e sporco per verificare gli argomenti.

3

Solo un suggerimento:

sia la soluzione da Wim Coenen e Patrick Steele sono corretti, ma, per la prima soluzione, molto veloce quando c'è solo un parametro, ci sono un messaggio di errore non corretto quando la prova fallisce.

Questo è un messaggio per la mia funzione con due parametri:

IProductChecker.MustPublish (pari a 2, pari a 123x); Previsto # 1, effettivo # 0.

Ora, quale dei due parametri è sbagliato? E se i parametri fossero di più?

ho preparato prova con questo codice:

//ARRANGE 
const string CLASSCODE = "ABC"; 
const string SUBCLASSCODE = "123X"; 
var expected = new [] {CLASSCODE, SUBCLASSCODE}; 

//ACT 
SUT.CallMyFunction(chkMock); 
var actual = chkMock.GetArgumentsForCallsMadeOn(m => m.MustPublish(null, null))[0]; 

//Assert 
CollectionAssert.AreEqual(expected, actual); 
//instead of 
//chkMock.AssertWasCalled(m => m.MustPublish(Arg<string>.Is.Equal("2"), Arg<string>.Is.Equal(SUBCLASSCODE))); 

Quindi, in questo caso il messaggio è:

CollectionAssert.AreEqual fallito. (Elemento in corrispondenza dell'indice 0 non corrispondono.)

Hi

Problemi correlati