Як використовувати web.config під час модульного тестування програми asp .net


74

Я починаю з модульного тестування, у мене є метод, який використовує web.config для рядка підключення.

Я сподівався, що зможу використовувати

[DeploymentItem("web.config")]

щоб отримати файл веб-конфігурації, це все ще залишає у мене винятки з нульовими посиланнями (для цього я буду писати наступний тест).

Як використовувати конфігураційний файл, що входить до проекту, який я намагаюся протестувати?

Я використовую основу тестування, включену в VS 2008, якщо це має якесь значення.

Дякую


Чи вставляєте ви свій тестовий код модуля в той самий проект, що і код вашої програми?
Gerrie Schenck

+1, у мене сьогодні було таке саме запитання. На жаль, я все ще не можу знайти відповідь, яку шукав, тому що те, що я хотів зробити, це додати посилання на поточний web.config у моєму веб-додатку і використовувати ці значення під час написання коду, інакше додавши app.config для моїх тестів не було б тестування конфігурації веб-програми, це частина інформації, яку я хочу протестувати під час розробки свого додатка. Однак має сенс не поєднувати тести з кодом, але це іноді важко зробити.
Eugenio Miró

Відповіді:


109

Проекти модульних тестів повинні мати власний файл конфігурації.

У тестовому проекті ви можете вибрати Додати, Новий елемент, Файл конфігурації програми.

Цей файл буде поводитися точно так само, як web.config, але тоді для ваших модульних тестів.


2
Я спробував те, що ви запропонували, і додав новий конфігураційний файл у свій тестовий проект. Рядок з'єднання на місці, але під час запуску тестів я завжди бачу значення null у рядку var sqlCon = new SqlConnection (ConfigurationManager.ConnectionStrings ["SqlServer"]. ConnectionString); Чого я можу пропустити?
ilivewithian

1
FWIW, я розмістив відповідь на подібне запитання ( stackoverflow.com/a/47355610/183174) [тут] . Суть полягає в тому, що ви можете переписати конфігураційні файли, які копіюються під час створення тестового проекту, проти VS.
LostNomad311

15

Ви можете завантажувати в web.config або app.config з будь-якого місця за допомогою OpenMappedExeConfiguration. Переконайтеся, що System.Configurationдодано до посилань вашого проекту.

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap()
fileMap.ExeConfigFilename = @"c:\my-web-app-location\web.config"

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
string connectionString = config.AppSettings.Settings["ConnectionString"].Value;

Ось web.config, досить стандартний.

<?xml version="1.0"?>
<configuration>
  <configSections>
  </configSections>
  <appSettings>
    <add key="ConnectionString" value="Data Source=XXXX;Initial Catalog=XXX; Trusted_Connection=True;"/>
  </appSettings>
</configuration>

Оновлення від 29.09.2017

Я придумав клас, щоб полегшити читання AppSetitngs з файлу. Я отримав ідею від Zp Bappi .

public interface IAppSettings
{
    string this[string key] { get; }
}

public class AppSettingsFromFile : IAppSettings
{
    readonly Configuration Config;

    public AppSettingsFromFile(string path)
    {
        var fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = path;
        Config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    }

    public string this[string key]
    {
        get
        {
            return Config.AppSettings.Settings[key].Value;
        }
    }
}

Ось як користуватися класом.

IAppSettings AppSettings = new AppSettingsFromFile(@"c:\my-web-app-location\web.confg");
string connectionString = AppSettings["ConnectionString"];

7

Скопіюйте файл web.config у папку "/ bin" та перейменуйте його в "AppName.dll.config".

Де "AppName" - це назва отриманої збірки.

Я використовував цей хак багато разів.


У мене це не спрацювало. Unit Test не знає автоматично про ConnectionString у файлі конфігурації. Мені потрібно написати власний код, щоб прочитати його з конфігурації.
орад

2
Додавання простого app.config, як у прийнятій відповіді, має працювати в більшості випадків. Це хак для деяких дивних конфігурацій (наприклад, "спеціальний тест" у TestDriven)
Олексій,

У мене це працювало з наступним налаштуванням у файлі .proj тестового проекту: <ItemGroup> <None Include = ".. \ MyProject \ Web.config"> <Link> $ (TargetFileName) .config </Link> <CopyToOutputDirectory> PreserveNewest </CopyToOutputDirectory> </None> </ItemGroup> Дякую
orad

4

Ви хочете, щоб ваші результати були чітко визначеними та повторюваними. Для цього вам потрібно буде попрацювати проти відомих даних, щоб ви могли чітко визначити як свої звичайні випадки, так і свої граничні випадки. У моїй роботі це завжди конкретний сервер та набір даних, тому модуль модульного тестування має вбудований рядок з'єднання. Інші воліють використовувати рядок з'єднання поза проектом Unit Testing. Я ніколи не бачив, щоб хтось рекомендував використовувати конфігураційний файл веб-сайту! (розробка чи інше)


1
Це має великий сенс, то яке рішення для отримання рядків підключення до мого додатка для тестування?
ilivewithian

Або жорстко кодуйте рядок підключення, який є специфічним для вашого середовища тестування (у нього поганий запах, але це насправді досить практично, оскільки він не має нічого спільного з кодом, що розгортається), або використовуйте файл конфігурації, визначений спеціально для модуля модульного тестування, як запропонувала Геррі .
Марк Бріттінгем

1
Тільки наголошу: я не припускаю, що ви коли-небудь жорстко кодуєте рядок підключення до бази даних у коді, який буде розгорнуто! У мене є конкретна база даних на певному сервері, яку я завжди використовую для модульного тестування. Перед тестуванням я запускаю сценарій, який гарантує, що db знаходиться у відповідному стані.
Марк Бріттінгем


1

Якщо вам потрібен рядок з'єднання, ви не пишете модульний тест (припускаючи, що використовуєте рядок з'єднання для переходу до бази даних). Блокові тести не повинні взаємодіяти із зовнішнім середовищем. Вам доведеться запускати всіх після кожної реєстрації, щоб вони краще бігали зі швидкістю світла.

Для модульного тесту ви захочете ізолювати свій код із бази даних. Змініть свої тести (і код, який ви тестуєте, якщо потрібно), щоб вам не потрібно було переходити до бази даних для їх тестування.


1
То ви пропонуєте мені не тестувати жодного коду, який отримує доступ до бази даних?
ilivewithian

3
Ні. Ваш код ніколи не повинен мати доступу до бази даних (якщо ви не пишете фреймворк бази даних). Натомість ви передаєте об’єкт коду, який отримує доступ до бази даних. У своїх модульних тестах ви глузуєте над цим об’єктом, у виробництві використовуєте фактичний клас доступу до бази даних.
Серхат Озгель

23
Я просто категорично не погоджуюся з цим на принциповому рівні. Це випробовує Unit Testing із сфери практичного, практичного інструменту для вдосконалення вашого коду, і перетворює його на абстракцію, обшиту штучними межами.
Марк Бріттінгем,

3
Функціональність бази даних можна перевірити за допомогою інтеграційних тестів, а не модульних тестів. І ви можете відокремити їх від своїх модульних тестів, щоб запускати модульні тести після кожної реєстрації та інтеграційні тести після кожної щоденної збірки або коли завгодно.
Серхат Озгель

6
Тут я повинен погодитися з Марком Бріттінгемом. Я знаю, що пуристи скажуть, що вам потрібно знущатись над даними, але що, якщо більша частина вашого коду є ітерацією рядків набору даних, що повертаються з бази даних? Якщо у вас є фіктивний об'єкт, тоді ви просто тестуєте "уявний" код, який був написаний з єдиною метою модульного тестування.
Henley Chiu,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.