2010-07-12 7 views
14

Soy nuevo en burlarse, y estoy teniendo dificultades para resolver un problema con UnitTesting.¿Cómo puedo usar Rhino Mocks para inspeccionar qué valores se pasaron a un método?

Decir que tengo este código:

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, así que quiero de probar la unidad del método Go. No me importa lo que el objeto _doer le haga al objeto una vez que lo consigue.

SIN EMBARGO, deseo inspeccionar qué ha recibido el objeto _doer.

en pseudo código que quiero lograr esto:

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

Es esto posible utilizando Rhino, y si es así, ¿cómo lo consigo?

aplausos

Respuesta

21

Con la nueva sintaxis Organizar/Ley/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

Creo que lo que tienes es bueno, así que sería:

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

a continuación, establecer la expectativa a través de:

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

luego, al final:

doer.VerifyAllExpectations(); 

EDITADO de Lee's respuestas a tener en cuenta que también puede hacer cosas como:

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

o

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

o pruebas similares cuando usted no quiere comparaciones exactas de referencia mediante el uso de los objetos Arg y Arg.

1

Si lo que desea es probar que la instancia MyClass pasa su parámetro a doer.Go a continuación, puedes configurar una expectativa:

SomeClass obj = new SomeClass { id = id }; 

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

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

doer.VerifyAllExpectations(); 

Sin embargo, si desea comprobar que pase algún objeto posiblemente diferente con algunos valor particular para una propiedad, entonces usted puede utilizar una restricción:

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

Todas estas respuestas brindan varias formas de hacer lo que desea y todas funcionan. Hay una cosa adicional a tener en cuenta. Si necesita obtener realmente "bajo nivel" y ver los argumentos pasados ​​a cualquier método anulado/burlado, puede usar GetArgumentsForCallsMadeOn.

Está un poco desordenado ya que devuelve el objeto [] []. Que lo utilice como esto (suponiendo que apagó stubber.InsertData aceptar nulo):

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

args [0] es un conjunto de parámetros pasados ​​a InsertData la primera vez que se llamaba.

args [1] es una matriz de parámetros pasados ​​a InsertData la segunda vez que se llamó.

etc ...

Así que si quería ver el valor entero pasado como el segundo parámetro de la primera invocación de un método que podría:

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

Una vez más, me gustaría recomendar una de los métodos anteriores, pero esto está disponible si necesitas ponerte realmente triste y sucio para ver los argumentos.

3

Sólo una sugerencia:

tanto la solución de Wim Coenen y Patrick Steele son correctas, pero, por primera solución, muy rápido cuando hay sólo un parámetro, hay un mensaje de error incorrecto cuando se prueba falla.

Este es un mensaje para mi función con dos parámetros:

IProductChecker.MustPublish (igual a 2, igual a 123X); Número esperado 1, real # 0.

Ahora, ¿cuál de los dos parámetros es incorrecto? ¿Y si los parámetros fueran más?

He preparado prueba con este código:

//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))); 

Por lo tanto, en este caso, el mensaje es:

CollectionAssert.AreEqual falló. (Elemento en el índice 0 no coinciden.)

Hola

Cuestiones relacionadas