2011-03-10 14 views
26

¿Es posible crear un simulacro de una clase que no proporcione un constructor sin argumentos y no pase ningún argumento al constructor? Tal vez con la creación de IL dinámicamente?Simulando objetos sin constructor sin argumentos en C#/.NET

El fondo es que no quiero definir interfaces solo para las pruebas. La solución alternativa sería proporcionar un constructor sin argumentos para probar.

+3

¿por qué no desea crear interfaces? Puede extraer fácilmente la interfaz de la clase y luego usar la interfaz en otro lugar. Creando menos dependencias y una mejor abstracción en tu código. –

+0

Hablando también de un uso de Moq para crear Mocks, necesitaría hacer los métodos virtuales. Parece que en ese caso una interfaz es generalmente mejor. No estoy seguro acerca de otros frameworks de Mocking. –

+3

Lo ideal es que las interfaces se utilicen en todo su código; frente a las implementaciones concretas, lo que hace que el comentario de "crear interfaces solo para probar" sea un punto discutible. –

Respuesta

38

cosa segura. En este ejemplo usaré Moq, una biblioteca de burla realmente impresionante.

Ejemplo:

public class MyObject 
{ 
    public MyObject(object A, object B, object C) 
    { 
      // Assign your dependencies to whatever 
    } 
} 

Mock<MyObject> mockObject = new Mock<MyObject>(); 
Mock<MyObject> mockObject = new Mock<MyObject>(null, null, null); // Pass Nulls to specific constructor arguments, or 0 if int, etc 

En muchos casos, sin embargo, asignar objetos Mock como los argumentos para que pueda probar las dependencias:

Mock<Something> x = new Mock<Something>(); 
MyObject mockObject = new MyObject(x.Object); 

x.Setup(d => d.DoSomething()).Returns(new SomethingElse()); 

etc 
+0

de acuerdo. Moq es increíble. Tienen una referencia de procedimientos completa en una página web. No puede ser eso por facilidad de uso/aprendizaje. –

+2

¿Funciona cuando el constructor requiere valores no nulos (con contratos de código o excepciones)? – deamon

+0

Por ejemplo, si tiene un número entero, puede pasar un 0. Si se trata de una cadena, Nulo, cadena. Vacío, etc. Puede ir casi por defecto (T), donde T: su tipo de parámetro y todo funciona multa. Si está creando un objeto simulado, los métodos/propiedades marcados como virtuales nunca se ejecutarán; puede controlar lo que hacen (a través de una devolución de llamada) o lo que devuelven (mediante el método de Retorno) en el objeto de simulacro. – Tejs

1

Es erróneo creer que está proporcionando interfaces solo para las pruebas. Las interfaces están ahí para proporcionar abstracciones y debilitar el acoplamiento entre las diferentes capas de su código haciéndolos más reutilizables en diferentes contextos.

Dicho esto, la respuesta dependerá del marco de simulación que esté utilizando. Por ejemplo, con burla de Rhino podría tener:

public class Foo 
{ 
    public Foo(string bar) 
    { } 

    public virtual int SomeMethod() 
    { 
     return 5; 
    } 
} 

y luego:

var fooMock = MockRepository.GeneratePartialMock<Foo>("abc"); 
fooMock.Expect(x => x.SomeMethod()).Return(10); 
+1

Depende de su punto de vista: Es cierto que un desarrollador debe escribir interfaces para debilitar el acoplamiento. Falso, un QA no quiere "mejorar" el código funcional solo para fines de prueba si puede omitir ese – PPC

Cuestiones relacionadas