Зачем вам писать юнит-тесты для контроллеров?


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. Речь идет не обязательно о языковых конструкциях, а о типе результата, возвращаемого контроллером. Хотя он может сводиться к тому же самому, когда у вас нет иерархии наследования, он становится совершенно другим зверем, когда контроллер ожидает возвращения Ancestors, контроллер возвращает Person, и теперь Person изменяется, чтобы происходить не от Ancestor, а от PeopleAncestor. ... также отвечает, почему тестирование такого метода может быть хорошей идеей ...;) Модульные тесты предназначены для выявления ситуаций, когда изменение одной вещи c / может сломать что-то другое.
— Марьян Венема


Скорее всего, я не трачу много времени на модульное тестирование точек входа приложения. Это похоже на модульное тестирование основного метода консольного приложения. просто имеет для меня очень мало смысла.
— Mvision

Ответы:


29

Ключевой момент здесь:

Я бы прекрасно знал, вернул ли этот контроллер искомый тип, выполнив метод в браузере.

Юнит-тестирование - это автоматизация нерегрессионного тестирования простых блоков кода, а не того, что вы смотрите сами. Вы не хотите делать себе всегда юнит-тестирование в своем приложении.

РЕДАКТИРОВАТЬ: Добавление комментария @anotherdave:

Речь идет о легкости масштабирования. Тестирование одного контроллера в браузере может быть в порядке; как насчет 10, 20, 50 контроллеров? Вы напишите тест один раз; вам может потребоваться обновить его, когда вы меняете контроллер, что накладные расходы. Но как часто вы развертываете? Конечно, ручная проверка каждый раз, когда есть намного больше накладных расходов, чем тест

В качестве альтернативы ответу @ Vladislav , модульное тестирование абсолютно всего может быть излишним, и действительно нежелательным. Если вам нужно что-то более легкое, вы можете провести нерегрессионное тестирование более высокого уровня с помощью Selenium. Конечно, вы получите меньшее покрытие, чем модульное тестирование, но вы можете получить приемлемое покрытие, которое стоит меньше времени на юнит-тестирование и является более гибким.

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


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

«Модульное тестирование - это автоматизация» - правильно, но также и интеграционное тестирование (Selenium / Webdriver / и т. Д.). Я не думаю, что это так уж необходимо, чтобы модульные тесты выполнялись быстрее, чем интеграционные тесты. Многое зависит от подхода, однако, если для получения эффективного модульного теста требуется макетирование дюжины различных сервисов и вызовов, сделанных в каждый из них, интеграционный тест может быть быстрее реализован и проще в обслуживании (хотя, как правило, намного медленнее, да) , Дело в том, что многое зависит от контекста и сложности тестируемого кода.
— Аромат

Добавлен комментарий @anotherdave
— Walfrat

@ Моя точка зрения была противоположной: полное модульное тестирование кода - это то, что отнимает много времени и делает код очень сложным для изменения без необходимости какого-либо модульного теста. Интеграционный тест легче. Конечно, вы хотите, чтобы модульное тестирование было чем-то очень сложным, но не потому, что вы тестировали этот компонент, вам нужно все тестировать. Еще раз мы видим людей, ищущих серебряную пулю там, где его нет.
— Вальфрат

24

Зачем вам писать юнит-тесты для контроллеров?

Потому что, не зная контекста, вы не можете точно сказать, нужно ли вам проверять то или иное. Вот несколько причин, почему вы можете захотеть протестировать контроллеры:

  • Контроллер может содержать сложную сервисную логику, которая подвержена ошибкам. Сами сервисы могут работать нормально, это результат, который вы хотите протестировать, и по какой-то причине вы решили не добавлять оркестровочный слой в свое приложение.
  • ваши контроллеры содержат ВЕСЬ бизнес-логику приложения, и контроллеры - это фактически все, что вы МОЖЕТЕ протестировать (пожалуйста, не делайте вид, что всю свою жизнь вы работали с идеальными кодовыми базами, такие программы есть, поверьте мне)
  • ваша команда состоит из 99% гениев и 1% средних людей, и вы хотите, чтобы этот 1% от ошибок в их зарплате

2
Я бы добавил: «Вы не можете предвидеть, кто в будущем собирается избавиться от проекта, и тесты являются частью самодокументированного кода»
— Laiv

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.