<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Burbujas en .NET : TDD</title><link>http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx</link><description>Etiquetas: TDD</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>[ALM 09] Material de las sesiones: Surface y TDD</title><link>http://geeks.ms/blogs/etomas/archive/2009/11/26/alm-09-material-de-las-sesiones-surface-y-tdd.aspx</link><pubDate>Thu, 26 Nov 2009 13:56:06 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:161345</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=161345</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/11/26/alm-09-material-de-las-sesiones-surface-y-tdd.aspx#comments</comments><description>&lt;p&gt;Hola a todos! Finalmente tuve el placer de dar no una, sino dos sesiones en las &lt;a href="http://www.microsoft.com/spain/visualstudio/ALM09/"&gt;ALM Sessions 09&lt;/a&gt;. No era la idea inicial, pero mi compañero Juan Carlos finalmente no pudo dar la de Surface, así que la di yo (y es que por suerte o por desgracia me encanta hablar).&lt;/p&gt;  &lt;p&gt;La primera sesión fue precisamente la de &lt;a href="http://www.microsoft.com/surface/"&gt;Surface&lt;/a&gt;, en el track de Diseño y UX. La intención inicial era haber traído la surface que tenemos en &lt;a href="http://www.raona.com"&gt;raona&lt;/a&gt;, pero por temas logísticos fue imposible… Así que tuve que dar una presentación sobre Surface sin Surface que es como una noche de fiesta sin lig… esto, que le falta algo, vamos. Intenté explicar un poco que es la Surface, y el cambio de paradigma que supone desarrollar para ella. Mostré el emulador que viene con el SDK de Surface (que os animo a todos a probar) y vimos algunos de los controles de dicho SDK. Finalmente exploramos el futuro que nos espera con WPF 4 unificando la programación multi-touch en Surface y en Windows 7.&lt;/p&gt;  &lt;p&gt;La segunda sesión, en el track de arquitectura, versó sobre TDD. Intenté explicar que es TDD, pero sobre todo &lt;em&gt;por que&lt;/em&gt; usar TDD sin entrar en detalles sobre el &lt;em&gt;como&lt;/em&gt; hacer pruebas unitarias (lo que daria para varias sesiones). Luego mencioné los pequeños cambios que trae VS2010 para hacernos llevadera la tarea de realizar TDD (recordad las sabias palabràs del &lt;a href="http://ca.wikipedia.org/wiki/Capit%C3%A0_Enciam"&gt;Capità Enciam&lt;/a&gt;: los pequeños cambios son poderosos) y empecé a desarrollar una clase usando TDD, intentando hacer énfasis en los &lt;em&gt;pensamientos&lt;/em&gt; que uno tiene gracias a usar TDD. Me quedé un poco corto de tiempo y tambien me comentaron que la combinación de colores que tengo en mi VS2010 será muy cómoda para programar pero muy mala para proyectar… Disculpas por si no pudisteis ver bien el código por culpa de los colores :(&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;En fin, que más puedo deciros: yo me lo pasé en grande durante todo el evento: dando sesiones, escuchándolas, hablando y conociendo a gente… ah si! y también comiendo y bebiendo jejejee… :)&lt;/p&gt;  &lt;p&gt;Os dejo las presentaciones de ambas sesiones.&lt;/p&gt;  &lt;p&gt;Un saludo y nos vemos en la próxima movida!!! ;)&lt;/p&gt;  &lt;p&gt;&lt;iframe style="border-bottom:#dde5e9 1px solid;border-left:#dde5e9 1px solid;padding-bottom:0px;background-color:#ffffff;margin:3px;padding-left:0px;width:240px;padding-right:0px;height:66px;border-top:#dde5e9 1px solid;border-right:#dde5e9 1px solid;padding-top:0px;" marginheight="0" src="http://cid-6521c259e9b1bec6.skydrive.live.com/embedrowdetail.aspx/Public/ALM%20Sessions%2009" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=161345" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/alm/default.aspx">alm</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx">TDD</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/eventos/default.aspx">eventos</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/surface/default.aspx">surface</category></item><item><title>ALM Sessions’09 – Test Driven Development</title><link>http://geeks.ms/blogs/etomas/archive/2009/11/17/alm-sessions-09-test-driven-development.aspx</link><pubDate>Tue, 17 Nov 2009 17:00:19 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:160708</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=160708</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/11/17/alm-sessions-09-test-driven-development.aspx#comments</comments><description>&lt;p&gt;Hola a todos!! Este año tengo el placer de realizar una presentación en las &lt;a href="http://www.microsoft.com/spain/visualstudio/alm09/"&gt;ALM Sessions’09&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;En concreto hablaré sobre Test Driven Development: que és, como su uso junto con otras buenas prácticas de desarrollo puede ayudarnos a ganar en calidad y como podemos implantarlo en un equipo de desarrollo.&lt;/p&gt;  &lt;p&gt; También veremos que herramientas trae Visual Studio 2010 y como nos pueden ayudar a realizar de forma más sencilla TDD.&lt;/p&gt;  &lt;p&gt;Os recomiendo que los que podais os paseis por Madrid este 24 de Noviembre, porque vale la pena. Si el año pasado las sesiones fueron buenas este año todavía más porque hay hasta 6 tracks simultáneos: Procesos, Calidad y testing, Herramientas, Arquitectura, Diseño/UX y Plataforma de aplicaciones. Si veis la &lt;a href="http://www.microsoft.com/spain/visualstudio/ALM09/agenda.aspx"&gt;agenda&lt;/a&gt; observaréis la gran cantidad de temas que se tratan. Es casi imposible no encontrar ninguno de vuestro interés!&lt;/p&gt;  &lt;p&gt;Un saludo y nos vemos por allí!!!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_0F9407C6.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="image" border="0" alt="image" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_38F76192.png" width="244" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=160708" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx">TDD</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/eventos/default.aspx">eventos</category></item><item><title>Pexcando errores en nuestro código…</title><link>http://geeks.ms/blogs/etomas/archive/2009/05/04/pexcando-errores-en-nuestro-c-243-digo.aspx</link><pubDate>Mon, 04 May 2009 09:03:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:148072</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=148072</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/05/04/pexcando-errores-en-nuestro-c-243-digo.aspx#comments</comments><description>&lt;p&gt;Buenas&amp;hellip; &amp;iquest;Conoceis &lt;a href="http://research.microsoft.com/en-us/projects/Pex/"&gt;Pex&lt;/a&gt;? Es una herramienta que genera tests unitarios a partir de nuestro c&amp;oacute;digo. Su caracter&amp;iacute;stica principal es que &lt;em&gt;analiza&lt;/em&gt; el c&amp;oacute;digo e intenta generar tests unitarios que cubran todas las posibilidades de nuestro c&amp;oacute;digo.&lt;/p&gt;
&lt;p&gt;Vamos a ver un peque&amp;ntilde;o ejemplo de como usarlo y como se integra con Microsoft Code Contracts. Antes que nada os recomiendo echar un vistazo al genial Post de Jorge Serrano &lt;a href="http://geeks.ms/blogs/jorge/archive/2009/04/26/precondiciones-y-microsoft-code-contracts.aspx"&gt;Precondiciones y Microsoft Code Contracts v1.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Vamos a hacer un m&amp;eacute;todo muy simple (y conocido por aquellos que desarrollen en VB.NET):&lt;/p&gt;
&lt;pre class="code"&gt; &lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringExtensions
&lt;/span&gt;{
     &lt;span style="color:blue;"&gt;public static string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;this string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
     {
         &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
     }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El m&amp;eacute;todo Right debe devolver los &amp;uacute;ltimos chars car&amp;aacute;cteres de la cadena value.&lt;/p&gt;
&lt;p&gt;Simplemente con este c&amp;oacute;digo nos descargamos &lt;a href="http://research.microsoft.com/en-us/projects/Pex/"&gt;Pex&lt;/a&gt; y lo instalamos. Una vez hecho vereis que nos aparece una nueva opci&amp;oacute;n el men&amp;uacute; contextual del &amp;ldquo;Solution Explorer&amp;rdquo; llamada &amp;ldquo;Run Pex Explorations&amp;rdquo;. Con esta opci&amp;oacute;n lo que hacemos es que Pex analice &lt;strong&gt;todo&lt;/strong&gt; nuestro c&amp;oacute;digo buscando generar Tests unitarios para nuestros m&amp;eacute;todos p&amp;uacute;blicos:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_0E628A6D.png"&gt;&lt;img height="81" width="224" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_3700F674.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Si ejecutamos esta opci&amp;oacute;n Pex analiza el c&amp;oacute;digo y nos genera tests unitarios para el m&amp;eacute;todo Right:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_3D47CD02.png"&gt;&lt;img height="43" width="499" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_61DBEB37.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;En este caso nos ha generado un solo test. Es importante saber como Pex genera los tests: no lo hace al azar, sin&amp;oacute; que intenta cubrir el m&amp;aacute;ximo de nuestro c&amp;oacute;digo. En nuestro caso como no nuestro c&amp;oacute;digo apenas hace nada, con un solo test, Pex obtiene una cobertura del 100% y se queda ah&amp;iacute;. Evidentemente Pex nada sabe de &lt;em&gt;cual debe ser el resultado&lt;/em&gt; de nuestro m&amp;eacute;todo, por lo que no puede generar tests unitarios funcionales.&lt;/p&gt;
&lt;p&gt;Ahora &lt;strong&gt;antes&lt;/strong&gt; de empezar a analizar c&amp;oacute;digo vamos a ver el uso de Code Contracts. Una vez instalada, a&amp;ntilde;ad&amp;iacute;s la referencia a &amp;ldquo;Microsoft Contracts Library&amp;rdquo; (Microsoft.Contracts.dll). En el framework 4.0 parece ser que se incluir&amp;aacute; el c&amp;oacute;digo dentro de mscorlib, por lo que no ser&amp;aacute; necesario usar referencia alguna.&lt;/p&gt;
&lt;p&gt;Ya estamos listos para definir los contratos en nuestra clase. Para ello debemos especificar las &lt;em&gt;precondiciones&lt;/em&gt; de nuestro m&amp;eacute;todo. Una &lt;em&gt;precondici&amp;oacute;n&lt;/em&gt; es algo que debe cumplirse s&amp;iacute; o s&amp;iacute; para asegurar que la llamada&amp;nbsp; anuestro m&amp;eacute;todo es &amp;ldquo;v&amp;aacute;lida&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Una precondici&amp;oacute;n de nuestro m&amp;eacute;todo es que NO vamos a aceptar que la cadena de entrada sea nula. El m&amp;eacute;todo Contract.Requires sirve para especificar las precondiciones:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;this string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
{
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(value !=&lt;span style="color:blue;"&gt;null&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si lanzamos Pex ahora vemos que&amp;hellip; no ocurre nada distinto. Esto es porque por defecto los contratos &lt;strong&gt;no se eval&amp;uacute;an&lt;/strong&gt;. Si queremos que se eval&amp;uacute;en debemos irnos a la pesta&amp;ntilde;a &amp;ldquo;Code Contracts&amp;rdquo; de las propiedades del proyecto y habilitar &amp;ldquo;Perform runtime contract checking&amp;rdquo;. Una vez hecho esto, volvemos a ejecutar Pex y obtenemos lo siguiente:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_31B4A074.png"&gt;&lt;img height="52" width="506" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_213C2F79.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Vemos que ahora Pex nos ha generado dos tests: uno que pase el contrato (le manda una cadena con un &amp;lsquo;\0&amp;rsquo; y otro que no (le manda null).&lt;/p&gt;
&lt;p&gt;Otra pecondici&amp;oacute;n que vamos a usar es que el segundo par&amp;aacute;metro debe ser mayor que cero:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;this string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
{
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(value !=&lt;span style="color:blue;"&gt;null&lt;/span&gt;);
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(chars &amp;gt; 0);
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una vez establecidas las precondiciones nos interesa establecer las &lt;em&gt;postcondiciones,&lt;/em&gt; es decir todo aquello que aseguramos que se cumple al finalizar el m&amp;eacute;todo. Para ello usamos Contract.Ensures. P.ej. para a&amp;ntilde;adir una postcondici&amp;oacute;n que asegure que nunca devolveremos null:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public static string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;this string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
{
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(value !=&lt;span style="color:blue;"&gt;null&lt;/span&gt;);
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(chars &amp;gt; 0);
    &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Ensures(&lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Result&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;() != &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una cosa realmente &lt;strong&gt;importante&lt;/strong&gt;: Contract.Ensures se eval&amp;uacute;a &lt;strong&gt;SIEMPRE&lt;/strong&gt; al final del m&amp;eacute;todo&amp;hellip; aunque como en este caso lo hayamos colocada &lt;em&gt;antes&lt;/em&gt; del return, se evaluar&amp;aacute; &lt;em&gt;despu&amp;eacute;s&lt;/em&gt; del return. El secreto est&amp;aacute; en que Code Contracts viene con un MSIL rewriter que modifica el c&amp;oacute;digo MSIL desplazando las llamadas a Contract.Requires al principio del m&amp;eacute;todo y de Contract.Ensures al final. El m&amp;eacute;todo Contract.Result&amp;lt;T&amp;gt; sirve para acceder al valor retornado por el m&amp;eacute;todo.&lt;/p&gt;
&lt;p&gt;Contract.Requires &lt;strong&gt;no&lt;/strong&gt; deja obsoleto a Debug.Assert. Ambos son necesarios: Con Contract.Requires comprobaremos las precondiciones l&amp;oacute;gicas de nuestro m&amp;eacute;todo, mientras que Debug.Assert lo seguiremos usando para comprobaciones de depuraci&amp;oacute;n (comprobaciones internas). &lt;/p&gt;
&lt;p&gt;Tenemos el contrato de nuestro m&amp;eacute;todo especificado, tenemos a Pex para que nos genere tests unitarios&amp;hellip; podemos empezar a meter c&amp;oacute;digo!&lt;/p&gt;
&lt;pre class="code"&gt; &lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringExtensions
&lt;/span&gt;{
     &lt;span style="color:blue;"&gt;public static string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;this string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
     {
         &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(value !=&lt;span style="color:blue;"&gt;null&lt;/span&gt;);
         &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Requires(chars &amp;gt; 0);
         &lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Ensures(&lt;span style="color:#2b91af;"&gt;Contract&lt;/span&gt;.Result&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;() != &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
         &lt;span style="color:blue;"&gt;if &lt;/span&gt;(chars &amp;gt;= value.Length) &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
         &lt;span style="color:blue;"&gt;else
         &lt;/span&gt;{
             &lt;span style="color:blue;"&gt;int &lt;/span&gt;inicial = value.Length - chars;
             &lt;span style="color:blue;"&gt;if &lt;/span&gt;(inicial &amp;lt; 0) inicial = 0;
             &lt;span style="color:blue;"&gt;return &lt;/span&gt;value.Substring(inicial, chars);
         }
     }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una vez tenemos el c&amp;oacute;digo ya listo (o eso creemos jejejeeee&amp;hellip;) relanzamos Pex para que nos cree un nuevo conjunto de tests unitarios para nuestro m&amp;eacute;todo. Como ahora tenemos un c&amp;oacute;digo un poco m&amp;aacute;s complejo, Pex nos crear&amp;aacute; varios tests unitarios:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_49DA9B80.png"&gt;&lt;img height="107" width="488" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_2236B007.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Pex ha creado 4 tests unitarios con el objetivo de cubrir al m&amp;aacute;ximo nuestro c&amp;oacute;digo. A partir de este punto si queremos podemos generar un proyecto de test con estos 4 tests unitarios. Los podemos seleccionar desde la ventana de Pex Exploration Results y le dais a &amp;ldquo;Save&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_1871488F.png"&gt;&lt;img height="76" width="497" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_63674A0F.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Con ello Pex nos genera el proyecto de tests unitarios:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_00DC2BCD.png"&gt;&lt;img height="115" width="261" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_3BC35E96.png" alt="image" border="0" title="image" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;El proyecto tiene dos archivos especiales: El fichero StringExtensionsTest.cs y el fichero StringExtensionsTest.Right.g.cs.&lt;/p&gt;
&lt;p&gt;El segundo (.g.cs) se regenera cada vez que ejecutamos Pex, por lo que NO debemos poner c&amp;oacute;digo en &amp;eacute;l. El primero por su parte se mantiene y contiene lo que Pex llama PUTs, o Parametrized Unit Tests. Un PUT es un test unitario pero que acepta par&amp;aacute;metros. Pex los usa para poder &amp;ldquo;agrupar&amp;rdquo; clausulas Assert: En lugar de colocar un Assert para cada test unitario, coloca uno de solo en el PUT y los tests unitarios que genera Pex, son llamadas al PUT con los par&amp;aacute;metros correspondientes.&lt;/p&gt;
&lt;p&gt;P.ej. el c&amp;oacute;digo del PUT generado es:&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;PexMethod&lt;/span&gt;]
&lt;span style="color:blue;"&gt;public string &lt;/span&gt;Right(&lt;span style="color:blue;"&gt;string &lt;/span&gt;value, &lt;span style="color:blue;"&gt;int &lt;/span&gt;chars)
{
    &lt;span style="color:green;"&gt;// TODO: add assertions to method StringExtensionsTest.Right(String, Int32)
    &lt;/span&gt;&lt;span style="color:blue;"&gt;string &lt;/span&gt;result = &lt;span style="color:#2b91af;"&gt;StringExtensions&lt;/span&gt;.Right(value, chars);
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;result;
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como se puede ver no hace nada salvo llamar al m&amp;eacute;todo real que estamos testeando pas&amp;aacute;ndole los par&amp;aacute;metros. Pero aqu&amp;iacute; nosotros podr&amp;iacute;amos poner Asserts adicionales, que se comprobar&amp;iacute;an para &lt;strong&gt;todos&lt;/strong&gt; los unit tests de Pex. El c&amp;oacute;digo de un unit test de Pex es similar a:&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;TestMethod&lt;/span&gt;]
[&lt;span style="color:#2b91af;"&gt;PexGeneratedBy&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;StringExtensionsTest&lt;/span&gt;))]
&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Right04()
{
    &lt;span style="color:blue;"&gt;string &lt;/span&gt;s;
    s = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Right(&lt;span style="color:#a31515;"&gt;&amp;quot;\0\0\0&amp;quot;&lt;/span&gt;, 1);
    &lt;span style="color:#2b91af;"&gt;Assert&lt;/span&gt;.AreEqual&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;\0&amp;quot;&lt;/span&gt;, s);
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La llamada a this.Right es la llamada al PUT que ha generado antes.&lt;/p&gt;
&lt;p&gt;Os dejo un par de videos con m&amp;aacute;s informaci&amp;oacute;n sobre Code Contracts y Pex para que les echeis un vistazo, dado que es un tema que vale realmente la pena!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/Peli/The-Synergy-of-Code-Contracts-and-Pex/" title="http://channel9.msdn.com/posts/Peli/The-Synergy-of-Code-Contracts-and-Pex/"&gt;http://channel9.msdn.com/posts/Peli/The-Synergy-of-Code-Contracts-and-Pex/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://channel9.msdn.com/pdc2008/TL51/"&gt;Research: Contract Checking and Automated Test Generation with Pex&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=148072" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx">TDD</category></item><item><title>IoC o el poder de ceder el control</title><link>http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx</link><pubDate>Tue, 28 Oct 2008 10:09:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:109560</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=109560</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx#comments</comments><description>&lt;p&gt;Hablando con colegas de profesión, me he dado cuenta de que muchos de ellos no terminan de comprender el patrón IoC o las ventajas que su uso comporta… Así que sin ánimo de sentar cátedra he decidido escribir este post, por si le sirve a alguien… &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;IoC, que corresponde a las siglas de Inversion Of Control, agrupa a varios patrones que tienen en común que el flujo de ejecución del programa se invierte respecto a los métodos de programación tradicionales (&lt;a href="http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_Control"&gt;wikipedia dixit&lt;/a&gt;). Generalmente el programador especifica las acciones (métodos) que se van llamando, pero en IoC lo que se especifican son las respuestas a determinados eventos o sucesos, dejando en manos de un elemento externo todas las acciones de control necesarias cuando lleguen estos sucesos.
&lt;/p&gt;&lt;p&gt;Un claro ejemplo de IoC se encuentra en el modelo de eventos de Windows Forms. Cuando vinculamos una función gestora a un evento (p.ej. el Click de un Button), estamos definiendo la respuesta a un determinado evento y nos despreocupamos cuando se llamará a nuestra función gestora. Es decir, cedemos el control del flujo al framework para que sea él que llame cuando sea necesario a nuestro método.
&lt;/p&gt;&lt;p&gt;Una de las principales ventajas de usar patrones IoC es que reducimos el acople entre una clase y las clases de las cuales depende, y eso cuando queremos utilizar por ejemplo tests unitarios es muy importante (no seré yo quien hable ahora de las ventajas de TDD cuando ya lo ha hecho Rodrigo (&lt;a href="http://geeks.ms/blogs/rcorral/archive/2006/12/02/beneficios-y-carater-iacute-sticas-de-un-buen-test-unitario.aspx"&gt;http://geeks.ms/blogs/rcorral/archive/2006/12/02/beneficios-y-carater-iacute-sticas-de-un-buen-test-unitario.aspx&lt;/a&gt;)). De los distintos patrones IoC me interesa comentar específicamente dos: Service Locator y cómo podemos usarlo en .NET. Para más adelante dejo Dependency Injection, otra forma de IoC que también es extremadamente útil.
&lt;/p&gt;&lt;p&gt; Id a la nevera, coged una &lt;a href="http://www.volldamm.es/"&gt;Voll-Damm&lt;/a&gt; o cualquier otra cervecilla y sentaos que este post es un poco largo… &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;
	&lt;/p&gt;&lt;h3&gt;Service Locator
&lt;/h3&gt;&lt;p&gt;El objetivo de Service Locator es reducir las dependencias que tenga una clase. Imaginemos una clase, que depende de otras dos clases (p.ej. ServicioSeguridad y ServicioLogin). Podríamos tener un código tal como:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;
			&lt;span&gt;Client
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;().Run();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Run()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="color:green;font-family:Courier New;font-size:10pt;"&gt;// En este punto necesitamos objetos de las clases ServicioSeguridad y ServicioLogger
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt; ss = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt; sl = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:green;"&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;En este punto tenemos un fuerte acople entre la clase Client y las clases ServicioSeguridad y ServicioLoggger. Seguiríamos teniendo este mismo acople incluso aunque utilizáramos interfaces porque deberíamos hacer el &amp;quot;new&amp;quot;:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioSeguridad&lt;/span&gt; ss = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioLogger&lt;/span&gt; sl = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Las principales desventajas de esta situación son:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Las clases que implementan las dependencias (en nuestro caso ServicioSeguridad y ServicioLogger) deben estar disponibles en tiempo de compilación (no nos basta con tener solo las interfaces).
&lt;/li&gt;&lt;li&gt;El fuerte acople de la clase con sus dependencias dificulta de sobremanera su testing. Si queremos utilizar Mocks para de ServicioSeguridad o ServicioLogger vamos a tener dificultades
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;El patrón de ServiceLocator soluciona estos dos puntos, sustituyendo las dependencias de la clase Client por dependencias a los interfaces y a un elemento externo, que llamaremos &lt;i&gt;Contenedor&lt;/i&gt; encargado de devolver las referencias que se le piden.
&lt;/p&gt;&lt;p&gt;Cuando la clase necesita un objeto en concreto, lo pide al contenedor:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioSeguridad&lt;/span&gt; ss = container.Resolve&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioLogger&lt;/span&gt; sl = container.Resolve&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;&amp;gt;(&lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;El método Resolve devolvería una referencia del tipo especificado en el parámetro genérico de acuerdo con un identificador. Evidentemente falta alguien que cree el contenedor y que agregue los servicios a él. Es decir, en algún sitio habrá algo como:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLogger&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;La gran diferencia es que esto no tiene porque estar en la clase &lt;i&gt;Client&lt;/i&gt;. Simplemente pasándole a la clase Client una referencia al contenedor, eliminamos todas las dependencias de la clase Client con las clases que implementan los servicios. Y donde creamos el contendor? Pues depende… si estamos en nuestra aplicación, lo podemos crear en el método que inicialice la aplicación, pero si queremos probar la clase Client con tests unitarios podemos crear el contenedor en la inicialización del test…. Y lo que es mejor: rellenarlo con Mocks de los servicios!
&lt;/p&gt;&lt;p&gt;Así, nuestro programa podría tener una clase Bootstrapper que crea el contenedor de IoC y lo inicializa con los objetos necesarios:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;
			&lt;span&gt;Bootstrapper
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      {
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IIoCContainer&lt;/span&gt; container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;            container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;            container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLogger&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;(container).Run();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Pero si queremos usar tests unitarios de la clase Client, podemos cambiar los objetos por Mocks fácilmente:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;[&lt;span&gt;ClassInitialize&lt;/span&gt;]
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
			&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Init(&lt;span&gt;TestContext&lt;/span&gt; context)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridadMock&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridadMock&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLoggerMock&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLoggerMock&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;[&lt;span&gt;TestMethod&lt;/span&gt;]
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; TestMethod1()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;Client&lt;/span&gt; c = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;(container);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      c.Run();            &lt;span style="color:green;"&gt;// Este método Run usará los Mocks!
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Fijaos que podemos lanzar tests unitarios sobre la clase Client, sin necesidad alguna de cambiar su código y utilizando Mocks. Además, la clase Client no tiene ninguna dependencia con las implementaciones de los servicios que utiliza, así que no es necesario ni que existan para poder crear la clase Client (sólo necesitamos las interfaces).
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Unity
&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Aunque existen varios contenedores IoC open source para .NET, Microsoft tiene el suyo, también open source, llamado Unity (&lt;a href="http://www.codeplex.com/unity/"&gt;http://www.codeplex.com/unity/&lt;/a&gt;). Unity proporciona soporte para los patrones Service Locator y Dependency Injection.
&lt;/p&gt;&lt;p&gt;Para que veais un poco su uso he dejado un proyecto de herramienta de línea de comandos para listar los ficheros de un directorio (vamos un dir, jejejee…. &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;).
&lt;/p&gt;&lt;p&gt;La solución está dividida en varios proyectos:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;DemoIoC: Contiene el Bootstrapper, la clase que inicializa el contenedor de Unity, agrega la clase llamada ServicioFicheros y utiliza un objeto Cliente para realizar las acciones de la línea de comandos.
&lt;/li&gt;&lt;li&gt;Cliente: Contiene la implementación de la clase Cliente.
&lt;/li&gt;&lt;li&gt;Interfaces: Contiene las interfaces del servicio (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;Implementations: Contiene las implementaciones del servicio (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;Mocks: Contiene las implementaciones de los Mocks (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;UnitTests: Contiene tests sobre la clase Cliente, usando un Mock del servicio ServicioFicheros.
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;El ejecutable (proyecto DemoIoC, assembly DemoIoC.exe) es un archivo de línea de comandos que acepta dos parámetros:
&lt;/p&gt;&lt;p&gt;DemoIoC –l para listar todos los ficheros (del directorio actual)
&lt;/p&gt;&lt;p&gt;DemoIoC –e:fichero.ext Indica si el fichero &amp;quot;fichero.ext&amp;quot; existe (en el directorio actual).
&lt;/p&gt;&lt;p&gt;Si lo ejecutáis veréis que NO funciona bien: lista los ficheros correctamente, pero devuelve que un fichero existe cuando no es cierto y viceversa. Si miráis el código de la clase Cliente, encontrareis el error, ya que es obvio, pero lo bueno es que el proyecto UnitTest, testea este método de la clase Cliente, usando un Mock del ServicioFicheros y el UnitTest detecta el error. Observad lo fácil que ha sido sustituir el ServicioFicheros por un Mock sin alterar la clase Cliente, gracias al uso del patrón Service Locator!
&lt;/p&gt;&lt;p&gt;PD: Estooooo... que me he dejado de adjuntar el código de ejemplo... Lo teneis &lt;a href="http://geeks.ms/blogs/etomas/IoC/DemoIoC.zip"&gt;aquí&lt;/a&gt;!!! &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Saludos!!!
&lt;/p&gt;&lt;h3&gt;Referencias
&lt;/h3&gt;&lt;p&gt;Os dejo algunas referencias para su lectura por si os interesa profundizar un poco en el tema tratado:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Unity Container (&lt;a href="http://www.codeplex.com/unity/"&gt;http://www.codeplex.com/unity/&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Patrón Service Locator (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707905.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707905.aspx&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Inversion of Control (&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc947917.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc947917.aspx&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Mocks (&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;http://martinfowler.com/articles/mocksArentStubs.html&lt;/a&gt;)
&lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=109560" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx">TDD</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category></item></channel></rss>