Как я могу написать модульный тест для класса контроллера, который использует winforms для представлений?
Кто-нибудь смог успешно выполнить юнит-тестирование методов, которые по необходимости связаны с классом System.Windows.Forms.Form?
Недавно я работал над приложением winforms на C#, пытаясь построить его со структурой MVC. Это достаточно сложно, учитывая, что фреймворк на самом деле не построен с учетом этого.
Тем не менее, это становится еще сложнее, когда вы бросаете юнит-тестирование в микс. Я следил за тем, чтобы мои контроллеры не были связаны с конкретными классами представления, чтобы я мог использовать заглушку / макет для модульного тестирования. Но ссылка на класс Form где-то неизбежна, и эти методы необходимо протестировать.
Я использую Moq, потому что он имеет несколько приятных функций безопасности типов и позволяет имитировать конкретные типы. Но, к сожалению, это не позволяет мне "ожидать" вызовов методов или свойств конкретного типа, которые не являются ни виртуальными, ни абстрактными. А поскольку класс Form не был создан с учетом подклассов, это большая проблема. Мне нужно иметь возможность макетировать класс Form, чтобы предотвратить создание реальных окон, например, "ожидая" ShowDialog.
Поэтому я не могу запустить какие-либо модульные тесты, которые сильно взаимодействуют с подклассами Form, как и мои взгляды.
Есть ли кто-нибудь, кто успешно тестировал этот тип кода? Как ты сделал это?
Это то, что другие насмешливые рамки могут обойти? Подходят ли к строковым методам, используемым другими насмешливыми средами, те же ограничения? Могу ли я написать свои собственные явные классы макетов с длинными руками, или недостаток виртуальных членов не позволит мне так же подавить поведение окна?
Или есть какой-то способ, которым я не задумывался структурировать свои классы так, чтобы код, связанный с Forms, заканчивался методами и классами тривиальной сложности, так что я мог обойтись без явного модульного тестирования их, без моей совести, избивающей меня для этого?
2 ответа
Лучший метод, который я слышал / использовал для модульного тестирования с элементами GUI, - это шаблон / метод Humble Dialog. По сути, формы - это просто интерфейс, и вся настоящая работа выполняется в других классах. Вы тестируете модули, которые предоставляют функциональность, а затем просто привязываете события GUI к соответствующим методам в этих классах.
В настоящее время я думаю, что мне, возможно, придется использовать композицию, а не наследование с классом Form, чтобы отделить контроллеры от него.
Это имеет тот недостаток, что каждый раз, когда мне нужно использовать член класса Form, который я не планировал, мне нужно явно добавлять его в интерфейс моего представления.