2012-07-31 11 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"); 
    } 
} 

Il metodo EmailService.SendEmail deve essere virtuale per deriderlo. C'è un modo per prendere in giro metodi non virtuali?Come simulare metodi non virtuali?

risposta

16

Moq non può simulare metodi non virtuali sulle classi. O usi altri framework di simulazione come Type mock Isolator che effettivamente tesse IL nell'assieme o inserisca un'interfaccia su EmailService e simuli quella.

4

L'alternativa a dover utilizzare i metodi virtuali per il mocking è utilizzare le interfacce. In questo modo puoi prendere in giro un'intera dipendenza.

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

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

Ora è possibile creare schernisce dell'interfaccia IEmailService per farvi deridere qualsiasi dei suoi metodi. Ovviamente, dovrai modificare i tipi di variabili contenenti oggetti EmailService su IEmailService, se necessario.

+0

Penso che l'utilizzo di questa tecnica sia buono e che ci siano sicuramente dei vantaggi nell'utilizzo delle interfacce. Ma se stai valutando tra le due opzioni che un metodo non virtuale può essere mockable: 1) renderlo virtual, 2) usarlo come parte dell'interfaccia, qual è il vantaggio di 2 su 1? Anche se scegli 2, stai effettivamente rendendo virtuale il metodo poiché ora fa parte di un'interfaccia. – zumalifeguard

7

La simulazione di metodi non virtuali implica l'utilizzo dell'API del profiler di basso livello. Al momento penso che le uniche opzioni disponibili sono:

entrambi sono commerciale, anche se JustMock dispone di una versione lite, beffardo metodi non virtuali sono disponibili solo con il commerciale versione. Come sottolineato nei commenti c'è qualcosa dalla ricerca Microsoft, nell'ambito del progetto Pex and Moles

+5

Penso che si possa aggiungere Microsoft Moles/Pex/Fakes a quella lista. Come bonus, è gratuito. – podiluska

+0

I falsi non sono inclusi nell'edizione Express di VS. –

1

Come @aqwert e @Felice scritto quando si utilizza Typemock Isolator è possibile (e abbastanza facile) di deridere i metodi non-virtuali senza aggiungere o modificare il codice , ad esempio:

[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); 
    } 

come puoi vedere il test che ho creato è simile al test che hai provato a creare.

Problemi correlati