Как проверить наличие ожидаемого исключения с конкретным сообщением об исключении из файла ресурсов в Visual Studio Test?
=========================================================================================================================

Visual Studio Test может проверять наличие ожидаемых исключений с помощью атрибута ExpectedException. Вы можете передать исключение следующим образом:

Вы также можете проверить сообщение, содержащееся в ExpectedException, например:

Но при тестировании приложений I18N я бы использовал файл ресурсов для получения этого сообщения об ошибке (любой может даже решить проверить различные локализации сообщения об ошибке, если я хочу, но Visual Studio не позволит мне сделать это:

Компилятор выдаст следующую ошибку:

An attribute argument must be a
 constant expression, typeof expression
 or array creation expression of an
 attribute

Кто-нибудь знает, как проверить исключение, которое имеет сообщение из файла ресурсов?

Одним из вариантов, который я рассмотрел, является использование пользовательских классов исключений, но на основе часто встречающихся рекомендаций, таких как:

"Do create and throw custom exceptions
 if you have an error condition that
 can be programmatically handled in a
 different way than any other existing
 exception. Otherwise, throw one of the
 existing exceptions." [Source](https://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx)

Я не собираюсь обрабатывать исключения по-разному в обычном потоке (это критическое исключение, поэтому я все равно перехожу в режим паники), и я не думаю, что создание исключения для каждого тестового случая - это правильная вещь. Есть мнения?

Just мнение, но я бы сказал, текст ошибки:

is part of the test, in which case getting it from the resource would be 'wrong' (otherwise you could end up with a consistantly mangled resource), so just update the test when you change the resource (or the test fails)
is not part of the test, and you should only care that it throws the exception.

Обратите внимание, что первый вариант должен позволять вам тестировать несколько языков, учитывая возможность запуска с локалью.

Что касается множественных исключений, то я с земли C ++, где допустимо (если не часто), но создание метаданных .Net допускает загрузку и загрузку исключений (с точностью до одного на оператор throw!) В больших heirachies. системе, вероятно, это не нравится, отсюда и этот совет.



Аргумент Сообщение ExpectedException не совпадает с сообщением об исключении. Скорее это сообщение, которое печатается в результатах теста, если ожидаемое исключение фактически не произошло.



Я думаю, что вы можете просто сделать явную попытку в своем тестовом коде вместо того, чтобы полагаться на атрибут ExpectedException, чтобы сделать это за вас. Затем вы можете найти какой-нибудь вспомогательный метод, который будет читать файл ресурсов и сравнивать сообщение об ошибке с сообщением об ошибке, которое было перехвачено. (конечно, если не было исключения, тогда контрольный пример следует считать неудачным)



Интересно, NUnit движется по пути от простоты ... но вот, пожалуйста.

**New enhancements (2.4.3 and up?) to the ExpectedException attribute allow you more control on the checks to be performed on the expected Exception via a Handler method**, Подробнее о[официальная страница NUnit doc](http://www.nunit.org/index.php?p=exception&r=2.4.3)... ближе к концу страницы.

Note: Something doesn't feel right here.. Why are your exceptions messages internationalized.. Are you using exceptions for things that need to be handled or notified to the user. Unless you have a bunch of culturally diverse developers fixing bugs.. you shouldn't be needing this. Exceptions in English or a common accepted language would suffice. But in case you have to have this.. its possible :)



Если вы переключитесь на использование очень приятно[xUnit.Net](https://codeplex.com/xunit) тестируя библиотеку, вы можете заменить [ExpectedException] на что-то вроде этого:



Я бы рекомендовал использовать вспомогательный метод вместо атрибута. Что-то вроде этого:

Затем вы можете написать свой тест примерно так:

Это также имеет то преимущество, что он проверяет, что исключение выдается на строке, которую вы ожидали, что оно будет сгенерировано, а не где-либо в вашем тестовом методе.



Я столкнулся с этим вопросом, пытаясь решить подобную проблему самостоятельно. (Я подробно опишу решение, на котором остановился ниже.)

Я должен согласиться с комментариями Гишу относительно интернационализации сообщений об исключениях, являющихся запахом кода.

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

В какой-то момент я рассмотрел (и протестировал) использование блоков try / catch, чтобы избежать требования к константе атрибутом ExpectedException, но это выглядело так, как будто это привело бы к большому количеству дополнительного кода при применении в большом масштабе.

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

Мой тестовый код тогда просто сводится к (простите за искажение ...):