Pregunta ¿Cuál es la diferencia entre fingir, burlarse y tropezar?


Sé cómo uso estos términos, pero me pregunto si hay definiciones aceptadas para fingir, burlóny troquelado para pruebas unitarias? ¿Cómo los defines para tus pruebas? Describe situaciones en las que podrías usar cada una.

Así es como los uso:

Falso: una clase que implementa una interfaz pero contiene datos fijos y ninguna lógica. Simplemente devuelve datos "buenos" o "malos" según la implementación.

Burlarse de: una clase que implementa una interfaz y permite la capacidad de establecer dinámicamente los valores a devolver / excepciones para arrojar desde métodos particulares y proporciona la capacidad de verificar si se han llamado / no llamado métodos particulares.

Talón: Como una clase falsa, excepto que no proporciona la capacidad de verificar que los métodos hayan sido llamados / no llamados.

Los simulacros y los talones pueden ser generados a mano o generados por un marco de burla. Las clases falsas se generan a mano. Uso burlas principalmente para verificar las interacciones entre mi clase y las clases dependientes. Utilizo stubs una vez que he verificado las interacciones y estoy probando rutas alternativas a través de mi código. Utilizo las clases falsas principalmente para abstraer las dependencias de datos o cuando los burms / stubs son demasiado tediosos para configurar cada vez.


520
2017-12-06 15:17


origen


Respuestas:


Puede obtener cierta información:

De Martin Fowler sobre Mock y Stub

Falso los objetos realmente tienen implementaciones de trabajo, pero generalmente toman algún atajo que los hace inadecuados para la producción

Talones proporcionar respuestas predefinidas a las llamadas realizadas durante la prueba, por lo general, no responde en absoluto a nada fuera de lo programado para la prueba. Los talones también pueden registrar información sobre llamadas, como un talón de la puerta de enlace de correo electrónico que recuerda los mensajes que 'envió', o tal vez solo la cantidad de mensajes que 'envió'.

Mocks son de lo que estamos hablando aquí: objetos preprogramados con expectativas que forman una especificación de las llamadas que se espera que reciban.

De xunitpattern:

Falso: Adquirimos o desarrollamos una implementación muy liviana de la misma funcionalidad provista por un componente del que depende el SUT e instruimos al SUT para que lo use en lugar del real.

Talón : Esta implementación está configurada para responder a las llamadas del SUT con los valores (o excepciones) que ejercerán el Código no probado (consulte Errores de producción en la página X) dentro del SUT. Una indicación clave para usar un Test Stub es tener un código no probado causado por la incapacidad de controlar las entradas indirectas del SUT

Objeto simulado que implementa la misma interfaz que un objeto del que depende el SUT (Sistema bajo prueba). Podemos usar un objeto simulado como punto de observación cuando necesitamos hacer una verificación de comportamiento para evitar tener un requisito no probado (ver Errores de producción en la página X) causado por la incapacidad de observar los efectos secundarios de invocar métodos en el SUT.

Personalmente

Intento simplificar usando: Mock y Stub. Uso Mock cuando se trata de un objeto que devuelve un valor que se establece en la clase probada. Uso Stub para imitar una clase Interface o Abstract para probar. De hecho, realmente no importa cómo lo llame, son todas las clases que no se usan en producción y se utilizan como clases de utilidad para las pruebas.


423
2017-12-06 16:17



Talón - un objeto que proporciona respuestas predefinidas a las llamadas a métodos.

Burlarse de - un objeto sobre el que establece expectativas.

Falso - un objeto con capacidades limitadas (para fines de prueba), p. un servicio web falso.

Test Double es el término general para stubs, mocks y fakes. Pero de manera informal, a menudo oirás que la gente simplemente los llama burlas.


157
2018-03-03 11:45



Me sorprende que esta pregunta haya existido durante tanto tiempo y nadie haya proporcionado una respuesta basada en "The Art of Unit Testing" de Roy Osherove.

En "3.1 Introducing stubs" define un stub como:

Un stub es un reemplazo controlable para una dependencia existente   (o colaborador) en el sistema. Al usar un stub, puedes probar tu código sin   lidiando con la dependencia directamente.

Y define la diferencia entre stubs y burlas como:

Lo principal que hay que recordar sobre los simulacros y los talones es que los simulacros son como talones, pero afirmas contra el objeto simulado, mientras que no afirmas contra un talón.

Fake es solo el nombre utilizado para los stubs y los simulacros. Por ejemplo, cuando no te importa la distinción entre stubs y mocks.

La forma en que Osherove distingue entre trozos y burlas, significa que cualquier clase utilizada como falso para probar puede ser tanto un trozo como un simulacro. Lo que es para una prueba específica depende completamente de cómo se escriban los controles en la prueba.

  • Cuando su prueba verifica los valores en la clase bajo prueba, o en cualquier otro lugar que no sea el falso, el falso se usó como un stub. Simplemente proporcionó valores para la clase bajo prueba para usar, ya sea directamente a través de los valores devueltos por las llamadas en él o indirectamente a través de causar efectos secundarios (en algún estado) como resultado de las llamadas en él.
  • Cuando su prueba verifica los valores de la falsificación, se utilizó como simulacro.

Ejemplo de una prueba donde la clase FakeX se usa como un stub:

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, cut.SomeProperty);

los fake instancia se utiliza como un trozo porque el Assert no usa fake en absoluto.

Ejemplo de una prueba donde la clase de prueba X se usa como simulacro:

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, fake.SomeProperty);

En este caso, el Assert comprueba un valor en fake, haciendo que ese falso sea un simulacro.

Ahora, por supuesto, estos ejemplos son altamente artificiales, pero veo un gran mérito en esta distinción. Te hace consciente de cómo estás probando tus cosas y dónde están las dependencias de tu prueba.

Estoy de acuerdo con Osherove en que

desde una perspectiva de mantenimiento puro, en mis pruebas de uso de simulaciones crea más problemas que no usarlos. Esa ha sido mi experiencia, pero siempre estoy aprendiendo algo nuevo.

Afirmar en contra de lo falso es algo que realmente quiere evitar, ya que hace que sus pruebas dependan en gran medida de la implementación de una clase que no es la que se prueba en absoluto. Lo que significa que las pruebas para la clase ActualClassUnderTestpuede comenzar a romper porque la implementación de ClassUsedAsMock cambiado Y eso me envía un mal olor. Pruebas para ActualClassUnderTest preferiblemente solo se rompa cuando ActualClassUnderTest está cambiado.

Me doy cuenta de que escribir afirma que la falsificación es una práctica común, especialmente cuando eres un tipo de suscriptor de TDD. Creo que estoy firmemente con Martin Fowler en el campo clasicista (ver "Mocks no son talones" de Martin Fowler) y al igual que Osherove, evite las pruebas de interacción (lo que solo se puede hacer afirmando contra el falso) tanto como sea posible.

Para divertirte leyendo sobre por qué debes evitar burlas como se define aquí, google para "Fowler Mockist Classicist". Encontrarás una plétora de opiniones.


71
2017-10-25 18:03



Para ilustrar el uso de stubs y burlas, me gustaría incluir también un ejemplo basado en Roy Osherove ".El arte de las pruebas unitarias".

Imagínese, tenemos una aplicación LogAnalyzer que tiene la única funcionalidad de imprimir registros. No solo necesita hablar con un servicio web, sino que si el servicio web arroja un error, LogAnalyzer debe registrar el error en una dependencia externa diferente y enviarlo por correo electrónico al administrador del servicio web.

Aquí está la lógica que nos gustaría probar dentro de LogAnalyzer:

if(fileName.Length<8)
{
 try
  {
    service.LogError("Filename too short:" + fileName);
  }
 catch (Exception e)
  {
    email.SendEmail("a","subject",e.Message);
  }
}

¿Cómo se prueba que LogAnalyzer llama correctamente al servicio de correo electrónico cuando el servicio web arroja una excepción? Aquí están las preguntas que enfrentamos:

  • ¿Cómo podemos reemplazar el servicio web?

  • ¿Cómo podemos simular una excepción del servicio web para que podamos prueba la llamada al servicio de correo electrónico?

  • ¿Cómo sabremos que el servicio de correo electrónico se llamó correctamente o al ¿todas?

Podemos ocuparnos de las primeras dos preguntas usando un stub para el servicio web. Para resolver el tercer problema, podemos utilizar un objeto simulado para el servicio de correo electrónico.

Un falso es un término genérico que se puede usar para describir un stub o un simulacro. En nuestra prueba, tendremos dos falsificaciones. Uno será el simulacro del servicio de correo electrónico, que usaremos para verificar que se enviaron los parámetros correctos al servicio de correo electrónico. El otro será un apéndice que usaremos para simular una excepción lanzada desde el servicio web. Es un apéndice porque no usaremos el servicio web falso para verificar el resultado de la prueba, solo para asegurarnos de que la prueba se ejecute correctamente. El servicio de correo electrónico es un simulacro porque afirmaremos que fue llamado correctamente.

[TestFixture]
public class LogAnalyzer2Tests
{
[Test]
 public void Analyze_WebServiceThrows_SendsEmail()
 {
   StubService stubService = new StubService();
   stubService.ToThrow= new Exception("fake exception");
   MockEmailService mockEmail = new MockEmailService();

   LogAnalyzer2 log = new LogAnalyzer2();
   log.Service = stubService
   log.Email=mockEmail;
   string tooShortFileName="abc.ext";
   log.Analyze(tooShortFileName);

   Assert.AreEqual("a",mockEmail.To); //MOCKING USED
   Assert.AreEqual("fake exception",mockEmail.Body); //MOCKING USED
   Assert.AreEqual("subject",mockEmail.Subject);

 }
}

6
2018-04-06 03:12



Es una cuestión de hacer las pruebas expresivas. Establezco expectativas en un simulacro si quiero que la prueba describa una relación entre dos objetos. Respaldo los valores devueltos si estoy configurando un objeto de apoyo para llevarme al comportamiento interesante en la prueba.


5
2018-05-21 18:36



Si está familiarizado con Arrange-Act-Assert, entonces una forma de explicar la diferencia entre el stub y el simulacro que podría ser útil para usted es que los stubs pertenecen a la sección de arreglos, ya que son para organizar el estado de entrada y los burlas pertenecen a la sección afirmar como están para afirmar los resultados en contra.

Los tontos no hacen nada. Solo son para llenar listas de parámetros, de modo que no obtenga errores indefinidos o nulos. También existen para satisfacer el verificador de tipos en lenguajes estrictamente tipados, por lo que se le puede permitir compilar y ejecutar.


1
2018-03-29 11:13



lo que afirmas en él, se llama burlarse de objeto y todo lo demás que ayudó a ejecutar la prueba, es un talón.


0
2017-07-21 12:07