Навіщо писати одиничні тести для контролерів?


22

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

public class ConstituencyControllerTests
{
    private ConstituencyController _constituencyController;
    private Mock<IConstituencyService> _IConstituencyServiceMock;

    public ConstituencyControllerTests() {
        _IConstituencyServiceMock = new Mock<IConstituencyService>();
    }

    [Test]
    public async Task I_Check_For_Return_Type_And_Result() {
        _constituencyController = new ConstituencyController( _IConstituencyServiceMock.Object );

        var result = await _constituencyController.Get();
        var content = ( (dynamic)result ).Content;

        Assert.IsEmpty( content );
        Assert.IsInstanceOf( typeof( System.Web.Http.Results.OkNegotiatedContentResult<IEnumerable<ListOfConstituencies>> ), result );
        _IConstituencyServiceMock.Verify( x => x.ListOfConstituencies(), Times.Once() );
    }
}


7
Не згоден з цим @gnat. Мова йде не про мовні конструкції обов’язково, а про тип результату, повернутого контролером. Хоча воно може зводитись до подібного, коли у вас немає ієрархії спадкування, він стає зовсім іншим звіром, коли контролер очікує повернення Предків, контролер повернув Особу, а тепер Людину змінили, щоб спуститися не від предка, а PeopleAncestor ... Також відповідає, чому тестування такого методу може бути хорошою ідеєю ...;) Тестові підрозділи мають на меті підбирати ситуації, коли зміна однієї речі c / порушить щось інше.
Мар'ян Венема


Як правило, погоджуюся, я зазвичай не витрачаю багато часу на тестування вхідних точок програми. Це як тестування основного методу консольного застосування. просто має для мене дуже мало сенсу.
Mvision

Відповіді:


29

Вони є ключовим моментом тут:

Я б чудово знав, якби цей контролер повернув потрібний тип, виконавши метод у браузері

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

EDIT: Додавання коментаря @anotherdave:

Йдеться про простоту масштабування. Тестування одного контролера в браузері може бути в порядку; як щодо 10, 20, 50 контролерів? Тест ви напишете один раз; Вам може знадобитися оновити його при зміні контролера, який є накладними. Але як часто ви розгортаєтесь? Безумовно, ручна перевірка щоразу, коли є набагато більше накладних витрат, ніж тест

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

Тобто, якщо ви перевіряєте все, що вам потрібно буде оновлювати один чи кілька тестів щоразу, коли ви змінюєте простий елемент.


4
Додамо також: I would know perfectly well if this controller returned the wanted type by executing the method in a browser.- йдеться про простоту масштабування. Тестування одного контролера в браузері може бути в порядку; як щодо контролерів 10, 20, 50? Тест ви напишете один раз; Вам може знадобитися оновити його при зміні контролера, який є накладними. Але як часто ви розгортаєтесь ? Безумовно, ручна перевірка щоразу, коли є набагато більше накладних витрат, ніж тест.
черговий день

"Тестування одиниць - це автоматизація" - Правильно, проте це тестування інтеграції (Selenium / Webdriver / тощо). Я не думаю, що це обов'язково так різати і сушити, що одиничні тести швидше реалізуються, ніж тести інтеграції. Багато залежить від підходу, однак якщо для отримання ефективного тестування підрозділу потрібно знущатися з десятка різних служб та дзвінків, що здійснюються в кожній, тест інтеграції може бути швидшим у впровадженні та простішим у обслуговуванні (хоча, як правило, запуск набагато повільніше, так) . Справа в тому, що багато що залежить від контексту та складності тестового коду.
aroth

@anotherdave коментар доданий
Walfrat

@aroth моя думка була навпаки, повний тестовий код - це те, що потребує багато часу і змушує код дуже важко змінити, не змінюючи тестування одиниці. Інтеграційний тест легший. Звичайно, ви хочете перевірити одиничне тестування чогось дуже складного, але це не тому, що ви перевірили цю частину, ви повинні все перевірити. І знову ми бачимо людей, які шукають срібну кулю там, де його немає.
Вальфрат

24

Навіщо писати одиничні тести для контролерів?

Тому що, не знаючи контексту, ти не можеш точно сказати, чи потрібно тестувати те чи інше. Ось кілька причин, чому ви можете перевірити контролери:

  • контролер може містити складну логіку службового проводки, яка схильна до помилок. Самі сервіси можуть спрацювати чудово - це результат, який ви хочете протестувати, і ви чомусь вирішили не вводити в додаток шар оркестрації.
  • ваші контролери містять ЦІЛУ логіку бізнесу програми та контролери - це фактично все, що ви МОЖЕТЕ протестувати (будь ласка, не претендуйте на те, що все життя ви працювали з ідеальними кодовими базами. Є такі бази кодів, повірте)
  • ваша команда складається з 99% геніїв і 1% середніх людей, і ви хочете, щоб 1% від помилок у їхній зарплаті

2
Я додам: "Ви не можете передбачити, хто в майбутньому збирається позбутися проекту, і тести є частиною коду, який
самодокументується

4
До середини, проект, який був створений без тестування на увазі, не може бути перевірений інакше, ніж тест контролера без макетів. Я працюю з командою C #, яка має саме такий проект у своїй опіці, тому вони пишуть контрольні тести, поки вони не зможуть додати необхідну структуру (інтерфейси тощо), щоб мати можливість більш детально тестувати.
Уейн Конрад

1

Я повністю згоден з ОП.

Тест блоку контролера є безглуздим. Ви перевіряєте контролери неявно за допомогою регресійних тестів (наприклад, використовуючи Selenium).

Ви повинні TDD всі компоненти / об'єкти, які використовує контролер, і тримати контролери якомога тонкішими. Тоді все перевірено належним чином. Що ви хочете бути впевнені, це те, що все працює добре під час виконання веб-запитів. Це тест регресії.


Можливо, так, але це не відповідь на питання. Насправді це аргумент проти використання одиничних тестів тут.
JᴀʏMᴇᴇ

Я думаю, що я відповів на питання "чи вважаєте ви тест для цього і для чого?"
winkbrace

Так, я думаю, що @winkbrace я поділяю однакові думки щодо цього. Але я також вважаю, що це дискусія про те, що ви повинні тестувати, а що ні. Я думаю, що люди випробовують занадто багато і "неправильних" речей. у моєму прикладі тестування контролера дає дуже мало значення, оскільки він такий тонкий і, сподіваємось, має тести навколо служб. Усі відповіді тут є змістовними і мають хороші моменти, але насправді неможливо відзначити одну як правильну відповідь.
заморозки

Логіку контролера можна перевірити, використовуючи автоматизовані тести інтеграції, окремі та відмінні від одиничних тестів для окремих компонентів.
KevBurnsJr

-1: Тест блоку контролера може бути безглуздим. Контролери стосуються трансформації, але іноді сама трансформація є складною, і розробник може захотіти, щоб це було охоплено. Я також думаю, що тести 1), в кінцевому рахунку, стосуються перевірки реалізації, не обов'язково перевірки поведінки високого рівня, і 2) повинні бути прокляті швидко . Обидві якості роблять одиничні тести набагато кориснішими під час впровадження; Іншими словами, вони в кінцевому рахунку є інструментом розробника і просто випадково способом перевірити якість продукції.
rsenna
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.