Dipendenza dalla dipendenza e derisione è tuo amico. Ogni volta che trovi qualcosa di difficile da testare, di solito significa che la tua classe ha troppe responsabilità. Suppongo che tu stia inviando le tue email usando una libreria. Probabilmente questa libreria prende le informazioni del tuo messaggio (indirizzo di destinazione, oggetto, corpo). Quello che vuoi fare è disgiungere la tua logica di business che è incaricata di raccogliere tutti gli indirizzi email, l'oggetto e il corpo dell'e-mail, da quella libreria di terze parti. Come? Sottragliando quella libreria usando un'interfaccia, e poi inserendola nella tua classe Email.
IEmailLibrary
{
void SendEmail(EmailInfo emailInfo);
}
class Email
{
private IEmailLibrary _emailLibrary;
public Email(IEmailLibrary emailLibrary)
{
_emailLibrary = emailLibrary;
}
public void SendEmailNotifications()
{
EmailInfo emailInfo = ComposeEmail();
_emailLibrary.SendEmail(emailInfo);
}
private EmailInfo ComposeEmail()
{
//your business logic
}
}
Ora nel tuo codice di produzione, dovresti creare una vera e-mailLibrary come questa:
public RealEmailLibrary : IEmailLibrary
{
...
public SendEmail(EmailInfo emailInfo)
{
_3rdPartyEmailComponent.SendEmail(emailInfo....);
}
}
e quindi inseriscilo nella tua classe di email, in questo modo:
RealEmailLibrary realEmailLibrary = new RealEmailLibrary();
Email email = new email(realEmailLibrary);
E se volevi testare la tua logica di business, tutto ciò che devi fare nel tuo codice di test, è inserire un finto, o il tuo stub che implementa un'interfaccia IEmailLibrary. Ad esempio:
public FakeEmailLibrary : IEmailLibrary
{
public EmailInfo _iWasCalledWithThisEmailInfo;
public void SendEmail(EmailInfo emailInfo)
{
_iWasCalledWithThisEmailInfo = emailInfo;
}
}
L'hai iniettato nel test in questo modo:
FakeEmailLibrary fakeEmailLibrary = new FakeEmailLibrary();
Email email = new email(fakeEmailLibrary);
email.SendEmailNotifications();
AssertStuff(fakeEmailLibrary.iWasCalledWithThisEmailInfo, expectedEmailInfo);
Raccomando l'uso di framework di simulazione, al contrario del mio esempio di stub (come Moq for C #), che rende molto semplice verificare che le dipendenze iniettate siano state chiamate con gli argomenti giusti.