with unit software setup mocks mock framework español ejemplos c# mocking tdd moq-3

c# - unit - moq software



Verifique el valor del parámetro de referencia con Moq (4)

Desafortunadamente, no estoy seguro de que esto sea posible sin el apoyo directo de Moq. El problema es que las expresiones Lambda no son compatibles con ref o out.

"Una expresión lambda no puede capturar directamente un parámetro de referencia o salida desde un método de cierre".

http://msdn.microsoft.com/en-us/library/bb397687.aspx

Ni siquiera puedo conseguir que un ejemplo como el tuyo funcione. La adición de ref a la configuración no se compila.

Es posible que desee consultar las discusiones de Moq para obtener más http://groups.google.com/group/moqdisc

Buena suerte.

Acabo de cambiar a Moq y me he encontrado con un problema. Estoy probando un método que crea una nueva instancia de un objeto comercial, establece las propiedades del objeto a partir de los valores de entrada del usuario y llama a un método (SaveCustomerContact) para guardar el nuevo objeto. El objeto de negocio se pasa como un argumento de referencia porque atraviesa una capa remota. Necesito probar que el objeto que se pasa a SaveCustomerContact tiene todas sus propiedades configuradas como se esperaba, pero debido a que se crea una instancia como nueva en el método del controlador, parece que no puedo hacerlo.

public void AddContact() { var contact = new CustomerContact() { CustomerId = m_model.CustomerId }; contact.Name = m_model.CustomerContactName; contact.PhoneNumber = m_model.PhoneNumber; contact.FaxNumber = m_model.FaxNumber; contact.Email = m_model.Email; contact.ReceiveInvoiceFlag = m_model.ReceiveInvoiceFlag; contact.ReceiveStatementFlag = m_model.ReceiveStatementFlag; contact.ReceiveContractFlag = m_model.ReceiveContractFlag; contact.EmailFlag = m_model.EmailFlag; contact.FaxFlag = m_model.FaxFlag; contact.PostalMailFlag = m_model.PostalMailFlag; contact.CustomerLocationId = m_model.CustomerLocationId; RemotingHandler.SaveCustomerContact( ref contact ); }

Aquí está la prueba:

[TestMethod()] public void AddContactTest() { int customerId = 0; string name = "a"; var actual = new CustomerContact(); var expected = new CustomerContact() { CustomerId = customerId, Name = name }; model.Setup( m => m.CustomerId ).Returns( customerId ); model.SetupProperty( m => model.CustomerContactName, name ); model.SetupProperty( m => m.PhoneNumber, string.Empty ); model.SetupProperty( m => m.FaxNumber, string.Empty ); model.SetupProperty( m => m.Email, string.Empty ); model.SetupProperty( m => m.ReceiveInvoiceFlag, false ); model.SetupProperty( m => m.ReceiveStatementFlag, false ); model.SetupProperty( m => m.ReceiveContractFlag, false ); model.SetupProperty( m => m.EmailFlag, false ); model.SetupProperty( m => m.FaxFlag, false ); model.SetupProperty( m => m.PostalMailFlag, false ); model.SetupProperty( m => m.CustomerLocationId, 0 ); remote .Setup( r => r.SaveCustomerContact( ref actual ) ) .Callback( () => Assert.AreEqual( actual, expected ) ); target.AddContact(); }

Este es solo el más reciente de los muchos intentos de obtener ese parámetro. Para referencia, el valor de real no cambia de su estado inicial (construido).

Mover Assert.AreEqual (esperado, real) después de que falle la llamada de destino. Si agrego .Verifiable () a la configuración en lugar de .CallBack y luego llamo a control remoto. Verifique después del objetivo (o, supongo, establezca el simulacro a estricto) siempre falla porque el parámetro que proporciono en la prueba no es el misma instancia que la que se crea en el método del controlador.

Estoy usando Moq 3.0.308.2. Cualquier idea sobre cómo probar esto sería apreciada. ¡Gracias!


La última versión de Moq soporta este escenario.

Tomado del inicio rápido en http://code.google.com/p/moq/wiki/QuickStart :

// ref arguments var instance = new Bar(); // Only matches if the ref argument to the invocation is the same instance mock.Setup(foo => foo.Submit(ref instance)).Returns(true);


Me he encontrado con un problema similar. Bit obtuve la solución usando el último Moq y pasando el valor como

var instance = new Bar (); Mock.Setup (foo => foo.Submit (ref instancia)). Devuelve (verdadero);

Anteriormente, también estaba usando el mismo método, pero no estaba obteniendo el retorno como verdadero.

Dentro de la función real, la instancia se creó y la sobrescritura de la instancia pasada desde la clase de prueba de la unidad causó el problema. Quité la creación de instancias dentro de la clase real y luego funcionó.

Espero que te ayude.

Gracias


No puedo ofrecerle una solución exacta, pero una alternativa sería ocultar la semántica paso a paso detrás de un adaptador, que toma el parámetro por valor y lo envía a RemotingHandler. Esto sería más fácil de burlar y eliminaría la verruga "ref" de la interfaz (siempre desconfío de los parámetros de ref :-))

EDITAR:

O puedes usar un código auxiliar en lugar de un simulacro, por ejemplo:

public class StubRemotingHandler : IRemotingHandler { public CustomerContact savedContact; public void SaveCustomerContact(ref CustomerContact contact) { savedContact = contact; } }

Ahora puede examinar el objeto guardado en su prueba:

IRemotingHandler remote = new StubRemotingHandler(); ... //pass the stub to your object-under-test ... target.AddContact(); Assert.AreEqual(expected, remote.savedContact);

También dices en tu comentario:

Odiaría comenzar un precedente de envolver bits aleatorios del backend para poder escribir pruebas más fácilmente

¡Creo que ese es exactamente el precedente que necesitas para establecer! Si tu código no es verificable, seguirás luchando para probarlo. Facilite la prueba y aumente su cobertura.