MVC na ASP.NET – Testování jednotek
|
Již delší dobu jsem chtěl napsat článek o tom, proč je MonoRail lepší, když chceme, aby se projekt dal testovat. Jenže vždycky nějak nebyl čas. Navíc se blíží vypuštění ASP.NET MVC, takže nakonec z toho bude trošku obecnější pojednání než jsem původně plánoval.
WebForms testování
Než si ukážeme jak snadné je testovat MVC, nejprve si povíme, že i WebForms se dají testovat. Ano, ale vyžaduje to větší kázeň a víc práce. :) Většinou stejně použijete MVP pattern nebo jeho blízké příbuzné. Pokud tedy nechcete psát testy, které simulují livecycle stránky a dekódují ViewState. (Ano, dotahuju to ad absurdum, ale i tak to může vypadat.)
Aby se tedy kód dal snadno testovat, měl by se co nejvíce oddělit od stránky.
Klasickým modelem tedy je využití MVP vzoru, kdy aspx stránka obsahuje pouze logiku pro prezentaci dat a implementuje rozhranní View, přes které komunikuje s Presenterem. Díky tomu, že Presenter obsahuje téměř veškerou logiku, je ideálním místem pro zacílení našich testů. Pro účely testů pak implementujeme stub nebo mock rozhranní view. Na něm pak sledujeme jak ho Presenter ovlivňuje.

Předchozí diagram ukazuj, že Presenter zná rozhranní View. Stránka, která toto rozhranní implementuje, se však musí postarat o to, aby byl presenter ve správnou chvíli zavolán. Možný scénář zachycuje ukázka kódu.
public class BlogViewPage : System.Web.UI.Page, IBlogView {
BlogPresenter presenter;
protected void Page_Init(object sender, EventArgs e) {
presenter = new BlogPresenter(this); // injekce View
}
protected void Page_Load(object sender, EventArgs e) {
presenter.LoadArticles();
}
// implementace IBlogView ...
}
Na to, že to stránka udělá správně, se už musíme spolehnout. Otestovat i takto jednoduchý kód, je už trošku náročnější práce…
MVC testování
MVC frameworky jako MonoRail nebo ASP.NET MVC, přicházejí s podobným schématem by default. V podstatě nás přímo nutí psát web tak, aby se dal lépe testovat. :) Nebudu přehánět, když řeknu, že ASP.NET MVC byl psán se zřetelí na velice snadné testování a obsahuje i sadu mock objektů (např. pro HttpContext
). MonoRail dokonce přináší i Fixtures a Asserty pro snadnější testování – bohužel jsou psané pouze pro NUnit, který nepoužívám.

Tento diagram se od předchozího mírně liší. Controller např. netuší jaké má View rozhranní, proto s ním nikterak nepracuje. Prostě zavolá RenderView(*název*, *objekt s daty*)
a spoléhá se na ViewFactory že všechno zařídí. Navíc stránka do poslední chvíle netuší, jestli něco bude dělat. Tady totiž proces zpracování začíná u routingu, který vybere správný controller, viz předchozí díl.
Dostáváme se i k lepšímu objektovému návrhu, kde každá třída je zodpovědná za provedení pouze jednoho úkolu (stránka v MVP těch úkolů řeší hned několik). To se opět lépe testuje. Máme sadu několika komponent s jednoduchými závislostmi a každá má na starosti pouze jednu část z procesu.
Pro dnešek to tady ukrouhnu. Bude-li nějaké příště, ukážeme si nějaké praktické ukázky. Možná :)
Okomentováno