c# - ¿Cómo obtengo shims para las clases base usando Microsoft Fakes?
microsoft-fakes (4)
class Parent{
public string Name{ get; set; }
}
class Child :Parent{
public string address{ get; set; }
}
[TestClass]
class TestClass{
[TestMethod]
public void TestMethod()
{
var c = new Fakes.Child();
c.addressGet = "foo"; // I can see that
c.NameGet = "bar"; // This DOES NOT exists
}
}
¿Cómo puedo establecer el "nombre" en el ejemplo de código anterior?
He reunido una solución basada en respuestas anteriores, la documentación de Microsoft y mi propia experimentación. También cambié un poco el TestMethod
para mostrar cómo lo usaría para las pruebas. Nota: no he compilado este código específico, por lo que me disculpo si no funciona como está.
[TestClass]
class TestClass
{
[TestMethod]
public void TestMethod()
{
using (ShimsContext.Create())
{
Child child = CreateShimChild("foo", "bar");
Assert.AreEqual("foo", child.address); // Should be true
Assert.AreEqual("bar", child.Name); // Should be true
}
}
private ShimChild CreateShimChild(string foo, string bar)
{
// Create ShimChild and make the property "address" return foo
ShimChild child = new ShimChild() { addressGet = () => foo };
// Here''s the trick: Create a ShimParent (giving it the child)
// and make the property "Name" return bar;
new ShimParent(child) { NameGet = () => bar };
return child;
}
}
No tengo idea de cómo el niño devuelto sabe que su Name
debe devolver "barra", ¡pero lo hace! Como puede ver, ni siquiera necesita guardar el ShimParent
ninguna parte; solo se crea para especificar el valor de la propiedad Name
.
La clase generada para Parent
tendrá un constructor que se parece a: ShimParent(Parent p)
.
Todo lo que necesitas hacer es:
var child = new ShimChild();
var parent = new ShimParent(child);
Y establecer los valores apropiados en los respectivos Shim''s.
Ninguno de los enfoques sugeridos hasta ahora funcionaría en mi opinión. Después de muchas pruebas y errores, encontré este código a continuación que me funcionó. Básicamente, tendrá que definir un delegado que inicialice su clase secundaria y, dentro de ese delegado, tendrá que conectar un Shim de padre de quien su clase secundaria debería heredar.
public void TestMethod()
{
//var c = new Fakes.Child();
//c.addressGet = "foo"; // I can see that
//c.NameGet = "bar"; // This DOES NOT exists
using (ShimsContext.Create())
{
ShimChild childShim = null;
ShimChild.Constructor = (@this) =>
{
childShim = new ShimChild(@this);
// the below code now defines a ShimParent object which will be used by the ShimChild object I am creating here
new ShimParent()
{
NameSetString = (value) =>
{
//do stuff here
},
NameGet = () =>
{
return "name";
}
};
};
}
}
Tendrás que declararlo en la clase base. La forma más fácil es llamar a la clase base su propiedad AllInstances:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
ClassLibrary1.Child myChild = new ClassLibrary1.Child();
using (ShimsContext.Create())
{
ClassLibrary1.Fakes.ShimChild.AllInstances.addressGet = (instance) => "foo";
ClassLibrary1.Fakes.ShimParent.AllInstances.NameGet = (instance) => "bar";
Assert.AreEqual("foo", myChild.address);
Assert.AreEqual("bar", myChild.Name);
}
}
}
También siempre intente agregar el ShimsContext para asegurar la limpieza adecuada de su calza. De lo contrario, sus otras pruebas de unidad también obtendrán los valores devueltos que ha declarado anteriormente. La información sobre ShimsContext se puede encontrar aquí: http://msdn.microsoft.com/en-us/library/hh549176.aspx#ShimsContext