2012-07-31 13 views
21
[TestMethod] 
public void TestMethod1() 
{ 
    var mock = new Mock<EmailService>(); 
    mock.Setup(x => x.SendEmail()).Returns(true); 
    var cus = new Customer(); 
    var result = cus.AddCustomer(mock.Object); 
    Assert.IsTrue(result); 
} 

public class Customer 
{ 
    public bool AddCustomer(EmailService emailService) 
    { 
     emailService.SendEmail(); 
     Debug.WriteLine("new customer added"); 
     return true; 
    } 
} 

public class EmailService 
{    
    public virtual bool SendEmail() 
    { 
     throw new Exception("send email failed cuz bla bla bla"); 
    } 
} 

El método EmailService.SendEmail debe ser virtual para simularlo. ¿Hay alguna forma de burlarse de los métodos no virtuales?¿Cómo burlarse de métodos no virtuales?

Respuesta

16

Moq no puede simular métodos no virtuales en las clases. Utilice otros marcos de burla como Type mock Isolator que realmente entrelazan IL en su conjunto o coloque una interfaz en EmailService y simule eso.

4

La alternativa a tener que usar métodos virtuales para burlarse es usar interfaces. De esta forma puedes burlar una dependencia completa.

public interface IEmailService 
{ 
    bool SendEmail(); 
    // etc... 
} 

public class EmailService : IEmailService 
{ 
    //... 
} 

Ahora puede crear burla de la interfaz IEmailService para hacerle burlas de cualquiera de sus métodos. Por supuesto, tendrá que cambiar los tipos de variables que contienen objetos EmailService a IEmailService, según corresponda.

+0

Creo que el uso de esta técnica es bueno, y sin duda hay ventajas en el uso de interfaces. Pero si está evaluando entre las dos opciones para que un método no virtual sea burlable: 1) hacerlo virtual, 2) usarlo como parte de la interfaz, ¿cuál es la ventaja de 2 sobre 1? Incluso si elige 2, entonces está haciendo que el método sea virtual, ya que ahora es parte de una interfaz. – zumalifeguard

7

Burlarse de métodos no virtuales implica el uso de perfil de baja API. En este momento creo que las únicas opciones disponibles son:

tanto son comerciales, aunque JustMock tiene una edición Lite, burlándose de métodos no virtuales están disponibles solo con el comercial versión. Como se señaló en los comentarios hay algo de investigaciones de Microsoft, en el proyecto Pex and Moles

+5

Creo que puede agregar Microsoft Moles/Pex/Fakes a esa lista. Como extra, es gratis. – podiluska

+0

Fakes no está incluido en la edición expresa de VS. –

1

Como @aqwert y @Felice escribió al utilizar Typemock Isolator es posible (y bastante fácil) para burlarse de los métodos no virtuales sin necesidad de añadir o cambiar ningún código , por ejemplo:

[TestMethod,Isolated] 
    public void TestMethod1() 
    { 
     var mock = Isolate.Fake.Instance<EmailService>(); 
     Isolate.WhenCalled(() => mock.SendEmail()).WillReturn(true); 
     var cust = new Customer(); 
     var result = cust.AddCustomer(mock); 
     Assert.IsTrue(result); 
    } 

como puede ver la prueba que he creado es similar a la prueba que intentó crear.

Cuestiones relacionadas