Модульный тест, который отправляет электронную почту и создает новую тему - PullRequest
4 голосов
/ 09 сентября 2011

Мне действительно плохо.

У меня есть одно веб-приложение, которое отправляет электронные письма для уведомлений.

Это класс, который содержит базовый метод, отправляющий электронное письмо, подобное этому:

 MailMessage email = new MailMessage();

        email.To.Add("xxx@gmail.com");

        email.Subject = "Test";
        email.Body = "t";

        SmtpClient client = new SmtpClient();

        client.Send(email);

Но у меня есть служба под названием NotificatorService, которая проверяет некоторую логику, и, поскольку это всего лишь «дополнительный», метод для этой службы вызывается в новом потоке. Что я делаю, так это:

public void NotifyMembers(NotificatorClientDTO clientDto) {
if(clientDto == null)
    throw new ArgumentNullException("clientDto");


Thread t = new Thread( 
    () => {
    // go to database, verify business rules, etc...

    // At the end if it is ok, invoke the method that sends a email
}

t.Start()

}

Если я создаю модульный тест, который создает экземпляр NotificatorService и вызывает notifyMembers с некоторыми данными, код выдаст исключение, но только если я выполню его в отдельном потоке.

Поток, который я создаю, настроен на foregronnd, поэтому система не разрушает мой процесс, я полагаю.

Сообщение об исключении:

SmtpException: невозможно оценить выражение, поскольку код оптимизирован или собственный фрейм находится над стеком вызовов

Я иду к двум внутренним исключениям и вижу это

_message "Тема была прервана." строка

Почему это происходит? Что вызывает прерывание потока?

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Измените свой юнит-тест, чтобы взять IMailService или что-то подобное в качестве зависимости Тогда вашему тесту модуля веб-приложения не нужно ничего делать реальный с точки зрения отправки электронных писем - он может использовать подделку или макет.

Затем вам нужно создать производственную реализацию IMailService, конечно, - и модульное тестирование , которое может все еще быть сложным, но, по крайней мере, тогда вы будете только заинтересованными тестирование обработки почты, что означает, что вы можете несколько изменить ограничения.

Вы потенциально можете сделать то же самое для стороны создания потока вещей. По сути, попытайтесь отделить «неприятные кусочки» вашего кода (которые взаимодействуют с почтовыми службами и потоками) от реальной логики, которую вы хотите проверить.

1 голос
/ 09 сентября 2011

Это похоже на интеграционный тест, а не модульный тест, как вы указали в заголовке вопроса.

Попробуйте добавить App.config в проект Tests.Assembly со следующим содержимым и посмотрите, поможет ли это:(играть с ApartmentState=MTA and ApartmentState=STA)

<?xml version="1.0" encoding="utf-8"?>

<configuration>
    <configSections>
        <sectionGroup name="NUnit">
            <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
        </sectionGroup>
    </configSections>

    <NUnit>
        <TestRunner>
            <add key="ApartmentState" value="STA" />
        </TestRunner>
    </NUnit>
</configuration>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...