tag:blogger.com,1999:blog-51316487097665087542024-03-19T05:37:36.915+01:00Un poquito de todoEl objetivo principal es compartir mis experiencias en la programación y gestión de proyectos de software, pero también un poco un sitio donde desahogarme y poder soltar tres o cuatro pensamientos que me llenan la cabeza a veces.
Osea, lector, no esperes maravillas. Aquí hay solo un hombre que se escribe así mismo.Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.comBlogger287125tag:blogger.com,1999:blog-5131648709766508754.post-19722856724130477492016-02-27T20:25:00.003+01:002016-02-27T20:25:26.740+01:00Me he migrado a WordPressNo sé en qué piensa Google, pero WordPress ha mejorado tanto como no lo ha hecho Blogger.<br />
<br />
Por lo cual migro el blog <a href="https://1poquitodtodo.wordpress.com/">Un Poquito de Todo</a> a esta nueva plataforma.<br />
<br />
Espero que el cambio sea permanente.Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-74639866852601557352016-02-27T13:13:00.001+01:002016-02-27T13:14:16.895+01:00¿Y si me voy a WordPress?<img height="456" src="https://static.betazeta.com/www.fayerwayer.com/up/2013/12/wordpress.png" width="640" /><br />
<br />
<br />
Estoy intentando conectar Windows Live Writer a esta cuenta de blogspot, y <b>es que no hay forma ninguna. </b>En cambio WorpPress va como una seda y el editor online es muchísimo más potente que este.<br />
<br />
Por lo cual no sería raro que haga una migración rápida y me vaya a WordPress, junto con mi blogs como <a href="https://futurekinect.wordpress.com/" target="_blank">Future Kinect</a>, <a href="https://naveganteestelar.wordpress.com/" target="_blank">Navegante Estelar</a> o el laboratorio de escritura <a href="https://loscuentosdelquijano.wordpress.com/" target="_blank">Los cuentos del Quijano</a><br />
<br />
<b>Ya veremos.</b><br />
<br />
<br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-17902891778118629982016-01-10T12:12:00.000+01:002016-01-10T12:13:57.343+01:00Año nuevo, nuevo diseño, nuevos contenidos<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.obs-edu.com/blog-investigacion/wp-content/uploads/sites/3/2013/06/ave-fenix.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://www.obs-edu.com/blog-investigacion/wp-content/uploads/sites/3/2013/06/ave-fenix.jpg" height="235" width="640" /></a></div>
<br />
<br />
La verdad que el diseño anterior del blog, en tonos verdosos, <b>me parece que no era un muestra del mejor gusto.</b> Incluso el más antiguo, en rojo, me gustaba más.<br />
<br />
Pero es que le estaba dedicando tan poco tiempo a este blog, que la verdad me importaba más el poquísimo contenido que le estaba añadiendo, que el formato del continente.<br />
<br />
Pero las cosas cambian y, ahora, necesito dos nuevos blog donde publicar nuevo contenido. <b>Este, en donde me voy a centrar en ALM y DevOps, y otro nuevo que se va a centrar en Azure y desarrollo para Cloud.</b><br />
<b><br /></b>
¿Esto a qué viene? Por un lado intentar cubrir el hueco de los grandes maestros de ALM sobre arquitectura Microsoft, <b>que se están yendo al extranjero o andan desaparecidos</b>. Por otro, mi nuevas responsabilidades en Avanade, que pasan por adquirir un conocimiento profundo en desarrollo para Azure.<br />
<br />
Y qué pasa con GenbetaDev y XatakaWindows? Pues XatakaWindows lo he dejado, y GenbetaDev estoy escribiendo poquísimo ya que no me siento motivado. Y menos ahora cuando quiero escribir sobre dos aspectos tan específicos de la tecnología.<br />
<br />
En cualquier caso, <b>voy a añadir un gran factor de material multimedia </b>(vídeos en youtube) porque así me lo han pedido y es algo que no he hecho nunca más allá de HangOut.<br />
<br />
Bueno, el tiempo dirá si finalmente cumplo mis propósitos para este año.<br />
<br />
<b>Feliz año 2016!!</b>Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0Rivas-Vaciamadrid, Madrid, España40.3519065 -3.535733400000026440.303501 -3.6164144000000267 40.400312 -3.4550524000000262tag:blogger.com,1999:blog-5131648709766508754.post-41255094235282637732016-01-04T14:03:00.000+01:002016-01-04T14:03:39.497+01:00Visual Studio 2015. Build Canceled en proyectos ASP.NETHay cosas que no me entran en la mollera, y una de ellas es el <b>ombligocentrismo </b>de algunas herramientas y de la gente que las construye.<br />
<br />
Todo esto viene porque desde hace unas semanas, en mi equipo de Avanade, cuando lanzo la compilación de un proyecto ASP.NET, se detiene nada más empezar con un escueto mensaje que dice "Build Canceled."<br />
<br />
Lo he probado todo, <b>he desinstalado el VS2015 dos veces y lo he vuelto a montar </b>- Full y con lo mínimo-, y nada. Esto que no tira.<br />
<br />
Lo he preguntado por twiter, y solamente un compañero me ha contestado con un chiste (que me ha hecho gracia y todo).<br />
<br />
Pero al final San <a href="http://stackoverflow.com/questions/5083291/build-has-been-canceled" target="_blank">Stack OverFlow</a> me ha salvado la vida.<br />
<br />
Hay una extensión de GetNug que permite habilitar el uso de JSLint en Visual Studio 2015; la cual es una librería de análisis estático de calidad de código en JavaScript; <b>y que por defecto está configurada con un parámetro que cancela la ejecución de la compilación</b>.<br />
<br />
Así que, raudo cual gacela, he entrado en la administración de Extensiones y Actualizaciones, dentro del menú Herramientas, y he deshabilitado la librería JSLint.<br />
<br />
Y todo ha vuelto a la normalidad!!<br />
<br />
Espero que sea de ayuda.Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-54158260946922780172015-07-14T16:15:00.001+02:002015-07-14T16:15:56.090+02:00VAN: ALM. Build Release Management.Aprovechando que he tenido que aprender, estimar y formar sobre temas de CI y Despliegue automatizado, he aprovechado la invitación de los colegas de AltNet Hispano para dar una charla ("ladrillo del carajo") sobre este tema.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="https://www.youtube.com/embed/G_1-lxbmzRE" width="480"></iframe><br /><br />
<br /><br />
Además, curiosidades del destino, cada vez encuentro más personas llegando a este proceso del ALM y que les vendrá bien este vídeo como una primera referencia.<br /><br />
<br /><br />
Espero que sea de utilidadJuan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-75782301004041267202015-05-15T16:24:00.000+02:002015-05-15T16:24:00.064+02:00Cómo ver la SQL que genera una query en Linq en tiempo de ejecución<p>Una de las cosas que muchas veces necesito es saber qué cadena SQL me ha construido Linq para explotar la base de datos (MSSQL).</p> <p>Hay varias herramientas para hacerlo, pero ninguna que yo conozca en tiempo de ejecución que sea más rápida que la Ventana Inmediato.</p> <p>Lo primero es que debo te tener puesto el punto de ruptura en donde el debuggeador esté dentro del contexto, por ejemplo en el fichero BL desde estoy haciendo llamadas al Entity. Por ejemplo si estoy haciendo un Select y me está dando un pete.</p> <p>Ctrl + Alt + i y abro la ventana, y allí escribo algo tal que así:</p> <p>? documentoBL.GetAll()</p> <p>Al dar Enter, me saldrá toda la Select que compone GetAll() y podré ver donde está el error.</p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-56687640960235736712015-05-14T10:00:00.001+02:002015-05-14T10:00:57.366+02:00Entity Framework – Invalid object name <tablename><p>Un error al parecer sencillo que me ha causado un dolor de cabeza.</p> <p>Tengo una tabla tal que así en la base de datos:</p> <p><a href="http://lh3.googleusercontent.com/-YmVwUmGMMjg/VVRWIMBRNOI/AAAAAAAADEU/q6km_I6dsmU/s1600-h/image%25255B4%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh3.googleusercontent.com/-sh2oIfNlkKE/VVRWI6VPTbI/AAAAAAAADEc/oPMuUQpnwTA/image_thumb%25255B2%25255D.png?imgmax=800" width="353" height="153"></a></p> <p>Tengo un mapeo tal que así:</p> <p><span style="background: white; color: blue">using </span><span style="background: white; color: black">System.Data.Entity.ModelConfiguration;<br><br></span><span style="background: white; color: blue">namespace </span><span style="background: white; color: black">ResNovae.Manager.DomainModel.Models.Mapping<br>{<br> </span><span style="background: white; color: blue">public class </span><span style="background: white; color: #2b91af">Clientes_ModuloYesMap </span><span style="background: white; color: black">: </span><span style="background: white; color: #2b91af">EntityTypeConfiguration</span><span style="background: white; color: black"><</span><span style="background: white; color: #2b91af">Cliente_ModuloYes</span><span style="background: white; color: black">><br> {<br> </span><span style="background: white; color: blue">public </span><span style="background: white; color: black">Clientes_ModuloYesMap()<br> {<br> </span><span style="background: white; color: green">// Primary Key<br> </span><span style="background: white; color: blue">this</span><span style="background: white; color: black">.HasKey(t => t.id_cliente_modulo);<br><br> </span><span style="background: white; color: green">// Table & Column Mappings<br> </span><span style="background: white; color: blue">this</span><span style="background: white; color: black">.ToTable(</span><span style="background: white; color: #a31515">"Clientes_ModuloYes"</span><span style="background: white; color: black">);<br><br> </span><span style="background: white; color: blue">this</span><span style="background: white; color: black">.Property(t => t.id_cliente_modulo).HasColumnName(</span><span style="background: white; color: #a31515">"id_cliente_modulo"</span><span style="background: white; color: black">);<br> </span><span style="background: white; color: blue">this</span><span style="background: white; color: black">.Property(t => t.id_cliente).HasColumnName(</span><span style="background: white; color: #a31515">"id_cliente"</span><span style="background: white; color: black">);<br> </span><span style="background: white; color: blue">this</span><span style="background: white; color: black">.Property(t => t.id_modulo_yes_iso).HasColumnName(</span><span style="background: white; color: #a31515">"id_modulo_yes_iso"</span><span style="background: white; color: black">);<br> }<br> }<br>}</span></p> <p><span style="background: white; color: black">Y cada vez que lanzo cualquier operación sobre la entidad me devuelve el error de que no encuentra la tabla…</span></p> <p><span style="background: white; color: black"><strong>NO LE DES VUELTAS, ES EL NOMBRE DEL MAPEO</strong></span></p> <p>Estoy tan acostumbrado a los mensajes crípticos de .NET o de (maldito mil veces) JavaScript, que no me creo cuando un mensaje de error dice <em>exactamente</em> cual es el error.</p> <p><span style="background: white; color: blue">this</span><span style="background: white; color: black">.ToTable(</span><span style="background: white; color: #a31515">"Clientes_Modulo<strong><u>s</u></strong>Yes"</span><span style="background: white; color: black">);</span></p> <p><span style="background: white; color: black">Me faltaba la maldita “s” de Modulos, no Modulo…</span></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com6tag:blogger.com,1999:blog-5131648709766508754.post-84995744372255479712015-03-11T16:49:00.000+01:002015-03-11T16:49:00.401+01:00Linq, select de todos los elementos que estén en un List<string><p>Tengo que recuperar de la base de datos todos los registros que en un campo tenga alguno de los valores que tengo almacenados en una lista de string.</p> <p><span style="background: white; color: blue">public </span><span style="background: white; color: #2b91af">IQueryable</span><span style="background: white; color: black"><</span><span style="background: white; color: #2b91af">entidad</span><span style="background: white; color: black">> Obtener(</span><span style="background: white; color: blue">int </span><span style="background: white; color: black">idCliente, </span><span style="background: white; color: #2b91af">List</span><span style="background: white; color: black"><</span><span style="background: white; color: blue">string</span><span style="background: white; color: black">>rango</span><span style="background: white; color: black">)<br> {<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">ctx = </span><span style="background: white; color: blue">new </span><span style="background: white; color: #2b91af">DataContext</span><span style="background: white; color: black">();<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">resultado = </span><span style="background: white; color: blue">from </span><span style="background: white; color: black">cliente </span><span style="background: white; color: blue">in </span><span style="background: white; color: black">ctx.Clientes<br> </span><span style="background: white; color: blue">where </span><span style="background: white; color: black">cliente.id_cliente == idCliente<br> && rango.Contains(cliente.id_rangos.ToString())</span><span style="background: white; color: black"><br> </span><span style="background: white; color: blue">select </span><span style="background: white; color: black">cliente;<br></span><span style="background: white; color: black"> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black"><span style="background: white; color: black">resultado ;</span><br> }</span></p> <p><span style="background: white; color: black">Lo que hace esto es seleccionar todos los registros que su campo (int)id_rangos esté dentro de los valores contenidos dentro de la lista de string rango.</span></p> <p><span style="background: white; color: black">El ToString() es para convertir el id_rangos (que es int) a cadena y que pueda ser comparado.</span></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-15646985161290181792015-02-10T22:05:00.001+01:002015-02-10T22:05:36.723+01:00Desarrollo móvil multiplataforma con Xamarin: Experiencias del mundo realUn Hangout excelente con grandes participantes. Todo un gusto.<br />
<br />
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="270" src="https://www.youtube.com/embed/iq48kcJerrY" width="480"></iframe>Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-89722014509287875892014-11-06T09:58:00.001+01:002014-11-06T09:58:07.774+01:00Propiedades booleanas cómo texto en MVC Razor<p> </p> <p>Un pequeño truqillo muy molón para evitar renderizar en la vista los horribles valor booleanos 1/0.</p> <p>Teniendo un Model con una propiedad booleana EstaActivo, lo declaro así en Razor</p> <p><span style="background: white; color: blue"><</span><span style="background: white; color: maroon">td</span><span style="background: white; color: blue">></span><span style="background: yellow; color: black">@(</span><span style="background: white; color: black">Model.EstaActivo == 0 ? </span><span style="background: white; color: #a31515">"Si"</span><span style="background: white; color: black">: </span><span style="background: white; color: #a31515">"No"</span><span style="background: yellow; color: black">)</span><span style="background: white; color: blue"></</span><span style="background: white; color: maroon">td</span><span style="background: white; color: blue">></span></p> <p>Fíjate que estoy utilizando un operador ternario, pero podría utilizar esta estructura para hacer algo más complejo (aunque intento evitar toda lógica de representación en la Vista).</p> <p>Pequeñito pero muy útil.</p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-18189452510704602992014-10-22T22:10:00.001+02:002014-10-22T22:10:37.678+02:00Lo que viene con C# 6Cuando un Hangout tiene de invitados a dos MVP de ASP.NET, C# y un MSP, difícil que no salga bien. Pero al final han sido dos horas tremendas de información y conocimiento, que se me han pasado volando y donde tengo material para aprender mucho.<br /><br />
<br /><br />
Imperdible.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="https://www.youtube.com/embed/GJRxxehddyc" width="480"></iframe><br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-2306209408973672332014-10-17T12:05:00.001+02:002014-10-17T12:08:05.343+02:00Error, TFS 2008 falla al cambiarle la contraseña a la cuenta del servicio<p><strong>Error retorcido y mala leche</strong> que proviene de cuando las cosas se hacían de otra manera en tiempos pasados, Gracias a Dios superados actualmente.</p> <p>Tengo una máquina virtual con un TFS2013 y otra con un TFS2008. Por motivos que no vienen al caso, <strong>he tenido que cambiar la contraseña de la cuenta de servici</strong>o (TFSSERVICE) que es la que ejecuta ambas instancias del servidor ALM.</p> <p>En el 2013 todo funciona correctamente sin ningún problema, pero en el TFS2008 me encuentro que – simplemente – ha dejado de funcionar.</p> <a name='more'></a> <p>Temiéndome lo peor entro en la máquina virtual y – efectivamente – <strong>ni el TFS ni el SharePoint me responden más que con un 405 – Service Unavailable</strong>. Y además me huele mucho al cambio de contraseña de la cuenta de ejecución.</p> <p>Así me voy a los servicios, los ordeno por la columna de “Iniciar sesión como” y le cambio la contraseña a todos los servicios que usen la cuenta TFSSERVICE.</p> <p><a href="http://lh5.ggpht.com/-KRa__fl38TA/VEDp41q5i1I/AAAAAAAAC8w/6ODK-eMdc5Y/s1600-h/image%25255B3%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-AZSyagHmNTo/VEDp5xbQ07I/AAAAAAAAC84/L1K661jOdz4/image_thumb%25255B1%25255D.png?imgmax=800" width="644" height="364"></a></p> <p>Reinicio la máquina, para asegurarme del cambio para cada servicio, pero esto sigue sin chutar. Por lo cual <strong>me voy al IIS y compruebo que los dos AppPool, tanto el del TFS como el del SharePoint, están detenidos por un error no especificado</strong>.</p> <p><a href="http://lh3.ggpht.com/-HV0uxmKLzRM/VEDp6nqcp_I/AAAAAAAAC9A/sUZZuNsf0IE/s1600-h/image%25255B7%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-U09ot27O52g/VEDp7OO-r6I/AAAAAAAAC9I/s10aTtsVEuo/image_thumb%25255B3%25255D.png?imgmax=800" width="644" height="354"></a></p> <p>Y aquí también debo de cambiar la contraseña a mano… en la pantalla de propiedades del AppPool, en la pestaña de identidades.</p> <p><a href="http://lh6.ggpht.com/-8FxSPziGkGM/VEDp71raq7I/AAAAAAAAC9Q/ZORbJlJ2JgQ/s1600-h/image%25255B11%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-njBPcNnkHl8/VEDp8ikxSgI/AAAAAAAAC9Y/uRuEVVZwC44/image_thumb%25255B5%25255D.png?imgmax=800" width="644" height="354"></a></p> <p>Debo de confirmar una segunda vez la nueva contraseña y ya me permite, iniciar el AppPool. A continuación vuelvo a hacer lo mismo en el AppPool del SharePoint y ya está todo el tema solucionado.</p> <p><a href="http://lh4.ggpht.com/-glIj-UpvXyg/VEDp-TauguI/AAAAAAAAC9c/CFIO8QVgi24/s1600-h/image%25255B18%25255D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-ysn-mD7yc-8/VEDp_N3AbXI/AAAAAAAAC9k/6r9iHokui0g/image_thumb%25255B8%25255D.png?imgmax=800" width="644" height="358"></a></p> <p><strong>Espero que sea de utilidad.</strong></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-31445868348834070272014-10-08T18:01:00.001+02:002014-10-17T12:08:42.862+02:00Agrupar Test Unitarios en listas<p>Si, <strong>demasiado tiempo sin escribir por aquí</strong>, pero es que entre GenbetaDev y mi nuevo blog de Kinect, tengo pocas cosas que decir en esta, mi memoria de código.</p> <p>Sin embargo estoy en un proyecto en donde somos varios desarrolladores, en donde yo pico mi propio proyecto en MVC + EF. Y en donde construyo mi propia batería de test, en medio de cienes de test de los demás desarrolladores.</p> <p>Y <strong>como no me fio un carajo de los test de los demás</strong> (hay cosas como DeleteAllCustomers_Test), solo quiero llevar el control y lanzar los míos.</p> <p>Y para eso Visual Studio 2013 me ofrece<strong> la posibilidad de construir listas de reproducción (playlist) </strong>de una muy sencillita.</p> <a name='more'></a> <p>Así, cuando cargo la solución me encuentro con este listado de test.</p> <p><a href="http://lh4.ggpht.com/-ymeHlmGBVvA/VDVflXCd8CI/AAAAAAAAC60/xb9NcVz8bb4/s1600-h/image3.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-J1XjUYSw3uc/VDVfmaeduKI/AAAAAAAAC68/2k4MJVrGPcA/image_thumb1.png?imgmax=800" width="334" height="484"></a></p> <p>Para poder localizar cuales son los míos, lo que hago es agrupar el listado por clase.</p> <p><a href="http://lh4.ggpht.com/-HA4vxKwUXMM/VDVfnnckMnI/AAAAAAAAC7E/mkBDPaaveUU/s1600-h/image17.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/--mdgZtYlStI/VDVfoaR62hI/AAAAAAAAC7M/IkaRQ5QU3eo/image_thumb9.png?imgmax=800" width="644" height="187"></a></p> <p>Obteniendo un listado mucho más manejable y en donde – desplegando los métodos de cada clase – accedo al listado de los test que quiero separar del resto.</p> <p><a href="http://lh5.ggpht.com/-idE95Fy3lQw/VDVfplNd_GI/AAAAAAAAC7U/LzOBC2jYRZE/s1600-h/image12.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-bAoDkNnMuQk/VDVfqiW_GlI/AAAAAAAAC7c/0KnJiV7axX8/image_thumb6.png?imgmax=800" width="334" height="484"></a></p> <p>El siguiente paso es seleccionar los métodos de los test que quiero añadir a la nueva lista (ojo, no vale seleccionar la clase), pulsar botón derecho para sacar el menú contextual en donde escoger “Add to PlayList –> New PlayList”</p> <p><a href="http://lh6.ggpht.com/-JYkZvnl84FQ/VDVfrhmuh-I/AAAAAAAAC7k/kShMEg1vGDs/s1600-h/image16.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-sBc_n_HN38o/VDVfs43_a_I/AAAAAAAAC7s/_RV4H1cOdKA/image_thumb8.png?imgmax=800" width="644" height="235"></a></p> <p>Se te abrirá una ventana para salvar directamente el fichero de la Playlist, y a partir de este momento me aparecerá la lista en el menú contextual como se ve en la figura superior.</p> <p>Ahora voy a utilizar la lista para poner un poco de orden en mis test, para lo cual me voy a los enlaces superiores y le digo que muestre la Playlist que acabo de dar de alta, <strong>reduciéndose los test disponibles a solamente los que hay en la lista de reproducción</strong>.</p> <p><a href="http://lh3.ggpht.com/-pTEAJtQbUJE/VDVftsmXoZI/AAAAAAAAC70/OZcJv520Vng/s1600-h/image21.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-dFlOb70a7d8/VDVfurOxWAI/AAAAAAAAC78/BotWjV4KfPw/image_thumb11.png?imgmax=800" width="334" height="484"></a></p> <p>Y para verlos todos, como me gusta a mi, simplemente debo ir de nuevo a el tipo de agrupación y situarlo en “Outcome”.</p> <p><a href="http://lh4.ggpht.com/-UURtJcppEaM/VDVfvWppF2I/AAAAAAAAC8E/yG9j_Ecq2uo/s1600-h/image25.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-CFEwGtmghSQ/VDVfwXaUT2I/AAAAAAAAC8M/7jWMINM4G6g/image_thumb13.png?imgmax=800" width="334" height="484"></a></p> <p><strong>Espero que sea de utilidad</strong></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-84332344882539860002014-07-18T19:55:00.001+02:002014-07-18T19:55:53.245+02:00Hangouts WINTABLET.INFO capítulo 8Interesantísimo Hangout en donde no dejamos títere sin cabeza y tocamos temas de actualidad y de desarrollo.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/qpoJ5VMqb3o" width="480"></iframe>Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-81910949175410494852014-07-05T00:56:00.001+02:002014-07-05T00:56:28.342+02:00Hangouts WINTABLET.INFO capítulo 7Una vez más, pasándolo en grande con los compañeros de Wintablet.info, diseccionando una Surface PRO 3 en directo.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/QiWZ1Wulf5M" width="480"></iframe><br /><br />
<br /><br />
Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-80652796896639095582014-07-02T22:29:00.001+02:002014-07-02T22:29:07.168+02:00Hablemos de blogs!Una charla con verdaderos veteranos de escribir blogs tecnológicos. Cuantos puntos de vista de una actividad que parece simple en n primer vistazo. Enriquecedor.<br /><br />
<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/MTUadCpwPQ4" width="480"></iframe><br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-8873933215104434852014-05-23T11:09:00.001+02:002014-05-23T11:09:35.939+02:00Hangout 4 de WINTABLET.INFOInteresantísimo debate de opiniones encontradas sobre la nueva SurfacePRO3, y en donde por una vez no soy pro Microsoft.<br /><br />
<br /><br />
Estos HangOut de Wintablet.info, cada vez tienen más nivel.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/gq_qyt7FVkc" width="480"></iframe><br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-67838607187394711722014-05-09T09:07:00.001+02:002014-05-09T09:07:02.772+02:00Hangout 3 de WINTABLET.INFO (+lista de reproducción)La tercera convocatoria de los HangOut de Wintablet.info.<br /><br />
<br /><br />
Una vez más me lo he pasado en grande con la temática, los conocimientos compartidos y el excelente ambiente que es capaz de generar el equipo de redacción<br /><br />
<br /><br />
Sobre BYOD y las noticias más golosas de los últimos quince dias.<br /><br />
<br /><br />
<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/71Wktgl2m44?list=UUzckA5MnqjwKZ5A2rUXW8kA" width="480"></iframe>LJuan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-83579795988143095382014-04-25T09:22:00.001+02:002014-04-25T09:22:35.390+02:00Hangout 2 de Wintablet.info<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/yHDqQq5qONo" width="480"></iframe>Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-32283054549939255952014-03-19T19:43:00.001+01:002014-03-19T19:43:35.812+01:00SignalR & WebAPI con Roberto<iframe allowfullscreen="" frameborder="0" height="270" src="//www.youtube.com/embed/fZSFpry_X2g" width="480"></iframe><br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-63466603921164811252014-03-18T10:47:00.001+01:002014-03-18T10:47:18.684+01:00Hangout SignalR y Web API con Roberto Bisbe<p>El viernes pasado, 14 de Marzo del 2014, tuve la suerte y el honor de compartir un HangOut con una de las más prometedoras figuras del mundo .NET actual, Roberto Bisbe.</p> <p>Mientras yo estuve farfullando generalidades sobre mi experiencia contruyendo la API para Echome, el nos dio una mini charla magistral sobre SignalR aplicado a la construcción de una app muy maja de votación en tiempo real.</p> <p>Me lo pasé muy bien, además de que apareció por allí Jorge Serrano, Gorka, David Salgado desde Redmond, Luís Fraile y más peña.</p> <p>La verdad que estos viernes me lo paso genial hablando con esta enorme colección de bestias pardas.</p> <p><a href="http://rlbisbe.net/2014/03/18/materiales-y-video-hangout-signalr-y-web-api/" target="_blank">Materiales y vídeo hangout SignalR y Web API</a></p> <div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:87ae239d-c59e-482a-bd3d-19e877c33cb7" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><div><object width="448" height="252"><param name="movie" value="http://www.youtube.com/v/fZSFpry_X2g?hl=en&hd=1"></param><embed src="http://www.youtube.com/v/fZSFpry_X2g?hl=en&hd=1" type="application/x-shockwave-flash" width="448" height="252"></embed></object></div></div> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com2tag:blogger.com,1999:blog-5131648709766508754.post-27766883938679277122014-02-26T19:02:00.001+01:002014-02-26T19:02:48.939+01:00Linq, recuperar número de filas y hallar la media en un join<p>Como tantas veces, estoy apasionado con una refactorización de código que me obliga a intentar ganar tiempo con Entity Framework, abandonado guarrerías de foreach y construyendo querys en Linq más complejas.</p> <p>Así tengo un negocio que tiene a su vez unos productos asignados. Lo que quiero es crear un objeto negocio que me incluya el número de productos que tiene y la media de la puntuación que han recibido todos.</p> <p><span style="background: white; color: black">resultado = (</span><span style="background: white; color: blue">from </span><span style="background: white; color: #2b91af">negocio negocio </span><span style="background: white; color: blue">in </span><span style="background: white; color: black">db.negocios<br> </span><span style="background: white; color: blue">where </span><span style="background: white; color: black">negocio.Id == pNegocio.Id</span><span style="background: white; color: black"><br></span></p> <p><span style="background: white; color: black"> </span><span style="background: white; color: blue">join </span><span style="background: white; color: #2b91af">negociositem </span><span style="background: white; color: black">item </span><span style="background: white; color: blue">in </span><span style="background: white; color: black">db.negociositems <br></span><span style="background: white; color: blue"> on </span><span style="background: white; color: black">negocio.Id </span><span style="background: white; color: blue">equals </span><span style="background: white; color: black">item.business_id </span><span style="background: white; color: blue">into </span><span style="background: white; color: black">items<br> </span></p> <p><span style="background: white; color: black"> </span><span style="background: white; color: blue">select new </span><span style="background: white; color: #2b91af">negocioconrating<br> </span><span style="background: white; color: black">{<br> Id = negocio.Id,<br> logo = negocio.logo,<br> name = negocio.name,<br><br> numrating = <span style="background: white; color: black">items</span>.Count(),<br> mediarating = <span style="background: white; color: black">items</span>.Average(p => p.rating),<br> <br> }).ToList<</span><span style="background: white; color: #2b91af">negocioconrating</span><span style="background: white; color: black">>();</span></p> <p>¿Que está ocurriendo aquí?</p> <p>Las primeras dos líneas son para seleccionar un negocio específico por medio de un parámetro llamado pNegocio que incluye un campo Id.</p> <p>A continuación hago un join (internamente un inner join) con la tabla negociositems para recuperar aquellos item que tengan el campo business_id igual al id del item seleccionado. Es importante que este resultado (el del join) lo almacene en una variable temporal llamada items, porque esto es lo que me permitirá realizar operaciones sobre el listado completo.</p> <p>Ahora hago un select sobre un nuevo objeto, en donde voy a almacenar los datos recuperados; así las primeras lineas son normales, cargando los resultados en las propiedades de la clase.</p> <p>Lo interesante son las dos últimas líneas del select. En la primera hago un Count() diréctamente y recupero el número de item que he recuperado. La segunda línea utiliza el método Average que soporta los objetos IEnumerable, y le paso una lambda como función; en la cual escojo el campo del cual quiero obtener la media.</p> <p>Una vez realizado parece sencillo, pero me ha tocado bucear un rato para encontrar estas dos soluciones.</p> <p>Espero que sea de ayuda.</p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com1tag:blogger.com,1999:blog-5131648709766508754.post-72830514706131767732014-02-14T21:30:00.001+01:002014-02-14T21:30:46.661+01:00BootCamp Iniciación al ALM con Visual Studio Online, en Tajamar<p>Aunque me haya costado dormir más bien poco durante tres días, he de reconocer que mi primera bootcamp en solitario ha sido todo un éxito.</p> <p>Durante más de 5 horas, que se me han echo muy cortas, he llevado de la mano a más de los 30 participantes en un viaje iniciático en la creación de un repositorio de código, sus primeros checkin, checkout, el primer etiquetado y la primera rama.</p> <p>En la segunda parte rozamos la gestión de tareas en <strong>ScrumBut</strong>, construyendo una Pila de Producto sencilla, definiendo la iteración, entendiendo lo que es una historia de usuario, una tarea y una Pila de Sprint. Todo ello sazonado de “<em>cuentos del abuelo cebolleta</em>” y muchos consejos basados en mi experiencia personal.</p> <p>La verdad que deseo expresar mi agradecimiento a <strong>Rafel Ansino</strong> por ofrecerme la oportunidad de disfrutar de las instalaciones de <strong>Tajamar</strong>, y del gran apoyo que me dio durante el largo evento. Al igual que a <strong>Cristian</strong> y a todos los asistentes.</p> <p>Espero veros en el segundo capítulo, ya con ALM Avanzado, que voy a celebrar el próximo 1 de Marzo (en las mismas instalaciones) siendo coparticipante de Luís Fraile</p> <p><a href="http://lh6.ggpht.com/-_RqEpiW42Yg/Uv588NmfDWI/AAAAAAAACzs/2d70Ev1uTao/s1600-h/WP_20140208_002%25255B4%25255D.jpg"><img title="WP_20140208_002" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="WP_20140208_002" src="http://lh6.ggpht.com/-jGYPpLbtuA4/Uv589IQHaHI/AAAAAAAACz0/Xp7yG-glxYQ/WP_20140208_002_thumb%25255B1%25255D.jpg?imgmax=800" width="644" height="364"></a></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com0tag:blogger.com,1999:blog-5131648709766508754.post-31941842278413757572014-02-09T13:35:00.000+01:002014-02-10T20:19:02.399+01:00Community Day 2014<span style="font-family: "Calibri","sans-serif"; font-size: 1pt; mso-ansi-language: ES; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: "Times New Roman"; mso-fareast-language: ES; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin;"><w:sdtpr></w:sdtpr><w:sdt docpart="B3DA892ECFB2496A9B57F28860EFD66E" id="89512082" storeitemid="X_5F329CAD-B019-4FA6-9FEF-74898909AD20" text="t" title="Título de la entrada de blog" xpath="/ns0:BlogPostInfo/ns0:PostTitle"></w:sdt></span>
<br />
<div class="Publishwithline" style="margin: 0cm 0cm 0pt;">
<span style="font-family: Calibri;">Un año más, y van tres,<strong> he podido disfrutar del evento de
comunidades técnicas de Microsoft</strong>. Un evento centrado principalmente en el
networking, en conversar con tantos buenos compañeros que habitualmente tratas solo
de forma virtual, y con quienes cada año tengo más afinidad.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Un evento de donde siempre salgo <strong>con agujetas en los
carrillos de tanto reírme</strong> y de pasarlo muy, muy bien.<o:p></o:p></span></div>
<span style="font-family: Calibri;">Además este año ha sido muy especial para mí, al pasar de
ser un mero asistente (que no es poco) a ser “<em>forzado</em>” por Bonnin a encargarme
de organizar y realizar tres mesas redondas, de una forma muy sorprendente ya
que no me lo notificó en ningún momento. De hecho, no llegue al inicio del
evento, y se me nombro como coordinador sin saberlo aún yo ;)<o:p></o:p></span><br />
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Por suerte junto con el padre de la idea, <strong>Juan Manuel Servera</strong>,
nos coordinamos y nos hemos llevado la sorpresa de una respuesta mayoritaria de
muchos de los asistentes; de la calidad de los debates y conversaciones que salieron
de estas reuniones casi auto organizadas (y eso que JuanMa y yo le
cambiamos los nombres, le cambios salas y horarios, y aun así estaban llenas);
y de las conclusiones y reflexiones que han emergido.</span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">El escuchar a un cliente de empresas referentes en nuestra
comunidad “<em>ponerle las pilas</em>”, <strong>es
algo de lo que se aprende mucho</strong> y te hace ver que no es todo oro lo que reluce,
y que la realidad es un cubo multidimensional que se puede analizar desde
muchos<span style="mso-spacerun: yes;"> </span>puntos de vista.<o:p></o:p><!------></span></div>
<span style="font-family: Calibri;">También he disfrutado mucho del debate que <span style="mso-spacerun: yes;"> </span>arrancó con una crítica feroz contra el modelo
de consultoría como el origen de todos los males, y que poco a poco consiguió hacer dejarnos
de mirar el ombligo y darnos cuenta que el problema es mucho más complejo.
Que implica a clientes, economía y a nosotros mismos como profesionales. Que
las empresas miran la informática (en general) <strong>como un coste y no como una
inversión</strong> que produce beneficios por medio del aumento de la productividad y el
ahorro de gastos. Y que si se nos percibiera tan buenos y necesarios como nos
vemos nosotros, aun así no hay garantía que los sueldos fueran mejores.<o:p></o:p></span><br />
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;"><strong>También DPE se apuntó a organizar<span style="mso-spacerun: yes;"> </span>mesas redondas</strong> y así Cristina invocó a todos
los MVP (<em>gracias por invitarme a asistir</em>) para debatir sobre un programa muy
interesante de mentoring de estudiantes MSP. Un programa que me parece de gran
potencial y que está muy relacionado con una conversación surgida en otra mesa
redonda sobre la resistencia feroz e injustificada que se percibe en la
universidad a todo lo que huela Microsoft por parte del cuerpo docente.<o:p></o:p></span></div>
<span style="font-family: Calibri;">Por su parte, José Bonnin, convocó a los más activos en la
comunidad para hablar de temas de gammificación, <strong>de los cuales sigo siendo muy incrédulo
en su aplicación</strong>. También buscamos fórmulas para mejorar la declinación de los
foros en España y Latam, para lo cual ha surgido un compromiso de una mayor coordinación entre los
moderadores, y en la que presenté mi ayuda a Luís Franco en lo que pueda
aportar.<o:p></o:p></span><br />
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Y llegó el final de los eventos técnicos, y llegamos a las
sesiones finales en donde los organizadores nos dieron las gracias a los
asistentes, <strong>los asistentes aplaudimos a rabiar e hicimos chistes de todo y de
todos;</strong> y aconteció el único “<em>pero</em>” de toda la reunión. </span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Por suerte, la cordura y el sentido común se impuso, y tanto
a Juan Manuel Servera como a mí, </span><strong style="font-family: Calibri;">los asistentes pidieran que nos obsequiará la
organización con un regalito </strong><span style="font-family: Calibri;">(un Nokia 710), que le he dado a Luis Fraile por
si le es útil en la asociación que preside.</span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Después, viajecito en moto a Aranjuez detrás de la BMW de
Fraile, y una cena muy animada, con muy buenos compañeros de mesa, y con una
interesantísima conversación con Rafael Ansino, Xavi y un MVP de CRM (que no me
acuerdo de su nombre).<o:p></o:p></span></div>
<span style="font-family: Calibri;">A la hora de las copas, salté de un corro a otro hasta
cuando me dispuse a partir hacia Madrid de vuelta, que al día siguiente tenía
mi primer bootCamp sobre introducción al ALM con Visual Studio Online en
Tajamar, y justo en ese momento Juan Manuel Servera, Luís Fraile, Asier (que
tampoco me acuerdo del apellido) <strong>damos por inaugurada una nueva comunidad
virtual: “Orgullo Backend”</strong>… ya os contaré.</span><br />
<span style="font-family: Calibri;"><o:p></o:p></span><br />
<span style="font-family: Calibri;">Muchas gracias a todos, coordinadores, y asistentes. Entre
todos hacéis que el orgullo de participar en esta comunidad, <strong>se convierta
además en un verdadero placer</strong>.</span><br />
<span style="font-family: Calibri;"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAwD5ZtGImVMWTQOqP4PdAxRHt9b17FqUirHcwwp9EweQGtFp4La9xJFR2EuQGlODCNHbIW9WZdskyCOR8OxcFqolYhDtTfeBsDmdjaVdxfBuUrjLkasnIqA4eNt0c4KKHBgoGu52iBpk/s1600/WP_20140207_004.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAwD5ZtGImVMWTQOqP4PdAxRHt9b17FqUirHcwwp9EweQGtFp4La9xJFR2EuQGlODCNHbIW9WZdskyCOR8OxcFqolYhDtTfeBsDmdjaVdxfBuUrjLkasnIqA4eNt0c4KKHBgoGu52iBpk/s1600/WP_20140207_004.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/HgA6Xwsa36c?feature=player_embedded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com1tag:blogger.com,1999:blog-5131648709766508754.post-22072200462622810332014-02-01T12:34:00.001+01:002014-02-01T14:49:09.766+01:00Test unitarios de un Controller que devuelve IHttpActionResult<p>Sigo con el intenso aprendizaje de construir una API REST con ASP.NET Web API, y me encontraba con el problema de que necesitaba poder realizar los test a los fallos que me estaban enviando los desarrolladores de las app que consumen este API.</p> <p>La parte buena de trabajar con Web API, es que utiliza´el patrón MVC, el cual me permite testear el controlador (incluso la vista si me pusiera), la dificultad es que nunca había testeado el interfaz de IHttpActionResult.</p> <p>Pero es bastante sencillo, y me ha mostrado una debilidad de mi formato de mensajes (que ya me habían avisado Ambrin y Julio).</p> <p>Voy a probar que el resultado de una operación es efectivamente un código de error específico.</p> <p>Para lo cual tengo una clase Error tal que así:</p> <p><span style="background: white; color: black"> </span><span style="background: white; color: blue">public class </span><span style="background: white; color: #2b91af">MensajeDeError<br> </span><span style="background: white; color: black">{<br> </span><span style="background: white; color: blue">public string </span><span style="background: white; color: black">Code { </span><span style="background: white; color: blue">get</span><span style="background: white; color: black">; </span><span style="background: white; color: blue">set</span><span style="background: white; color: black">; }<br> </span><span style="background: white; color: blue">public string </span><span style="background: white; color: black">Message { </span><span style="background: white; color: blue">get</span><span style="background: white; color: black">; </span><span style="background: white; color: blue">set</span><span style="background: white; color: black">; }<br> </span><span style="background: white; color: blue">public string </span><span style="background: white; color: black">MessageDetail { </span><span style="background: white; color: blue">get</span><span style="background: white; color: black">; </span><span style="background: white; color: blue">set</span><span style="background: white; color: black">; }<br> </span><span style="background: white; color: blue">public string </span><span style="background: white; color: black">MoreInfo { </span><span style="background: white; color: blue">get</span><span style="background: white; color: black">; </span><span style="background: white; color: blue">set</span><span style="background: white; color: black">; }<br></span><span style="background: white; color: black"> }</span></p> <p><span style="background: white; color: black">El Controlador que voy a testear es algo tal que así:</span></p> <p><span style="background: white; color: black"></span><span style="background: white; color: black"> [</span><span style="background: white; color: #2b91af">HttpPost</span><span style="background: white; color: black">] </span><span style="background: white; color: blue">public </span><span style="background: white; color: #2b91af">IHttpActionResult </span><span style="background: white; color: black">PostItem(</span><span style="background: white; color: #2b91af">negociositem </span><span style="background: white; color: black">item)<br> {<br> </span><span style="background: white; color: blue">if </span><span style="background: white; color: black">(item != </span><span style="background: white; color: blue">null</span><span style="background: white; color: black">)<br> {<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">accion = </span><span style="background: white; color: blue">new </span><span style="background: white; color: #2b91af">Items</span><span style="background: white; color: black">();<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">error = </span><span style="background: white; color: blue">new </span><span style="background: white; color: #2b91af">MensajeDeError</span><span style="background: white; color: black">();<br><br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">resultado = accion.AddItem(item, </span><span style="background: white; color: blue">out </span><span style="background: white; color: black">error);<br><br> </span><span style="background: white; color: blue">if </span><span style="background: white; color: black">(error.Code == </span><span style="background: white; color: #2b91af">ObtenError</span><span style="background: white; color: black">.Sin_error().Code)<br> { </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">Json(resultado); }<br> </span><span style="background: white; color: blue">else<br> </span><span style="background: white; color: black">{ </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">Json(error); }<br> }<br> </span><span style="background: white; color: blue">else<br> </span><span style="background: white; color: black">{<br> </span><span style="background: white; color: blue">return </span><span style="background: white; color: black">Json(</span><span style="background: white; color: #2b91af">ObtenError</span><span style="background: white; color: black">.Item_no_valido());<br> }<br> }</span></p> <p>Como creo que se lee fácilmente, lo que hago es intentar persistir un item. Y si tengo algún error, lo que me devuelve (en vez del objeto resultado) un objeto mensaje de error. (Y aquí está la debilidad de devolver dos mensajes diferentes).</p> <p>¿Cómo pruebo esto? Haciendo un test que fuerce un error, y comprobando que el código de error sea el esperado.</p> <p><span style="background: white; color: blue">using </span><span style="background: white; color: black">api.Controllers;<br></span><span style="background: white; color: blue">using </span><span style="background: white; color: black">api.Entidades;<br></span><span style="background: white; color: blue">using </span><span style="background: white; color: black">System.Web.Http.Results;<br></span><span style="background: white; color: blue">using </span><span style="background: white; color: black">Microsoft.VisualStudio.TestTools.UnitTesting;<br><br></span><span style="background: white; color: blue">namespace </span><span style="background: white; color: black">api.Controllers.Tests<br>{<br> [</span><span style="background: white; color: #2b91af">TestClass</span><span style="background: white; color: black">()]<br> </span><span style="background: white; color: blue">public class </span><span style="background: white; color: #2b91af">ItemsControllerTests<br> </span><span style="background: white; color: black">{<br> [</span><span style="background: white; color: #2b91af">TestMethod</span><span style="background: white; color: black">()]<br> </span><span style="background: white; color: blue">public void </span><span style="background: white; color: black">PostItemTest()<br> {<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">accion = </span><span style="background: white; color: blue">new </span><span style="background: white; color: #2b91af">ItemsController</span><span style="background: white; color: black">();<br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">item = </span><span style="background: white; color: blue">new </span><span style="background: white; color: #2b91af">negociositem </span><span style="background: white; color: black">{ business_id = 0, <br> name = </span><span style="background: white; color: #a31515">"borrame"</span><span style="background: white; color: black">, <br> description = </span><span style="background: white; color: #a31515">""</span><span style="background: white; color: black">, <br> origin = 2, picture = </span><span style="background: white; color: #a31515">"" </span><span style="background: white; color: black">};<br><br> </span><span style="background: white; color: blue">var </span><span style="background: white; color: black">resultado = accion.PostItem(item);<br><br> </span><span style="background: white; color: #2b91af">Assert</span><span style="background: white; color: black">.AreEqual(</span><span style="background: white; color: #a31515">"503"</span><span style="background: white; color: black">, ((</span><span style="background: white; color: #2b91af">JsonResult</span><span style="background: white; color: black"><api.</span><span style="background: white; color: #2b91af">MensajeDeError</span><span style="background: white; color: black">>)resultado).Content.Code);<br> }<br> }<br>}</span></p> <p><span style="background: white; color: black">¿Qué es lo importante aquí?</span></p> <p><span style="background: white; color: black">Primero asegurarme que me estoy importando al proyecto de Testing los namespaces adecuados. Es decir, los que contienen los tipos de objeto que voy a usar (Controllers, y Entidades), y el interfaz de respuesta (<span style="background: white; color: black">System.Web.Http.Results).</span></span></p> <p><span style="background: white; color: black"><span style="background: white; color: black">Segundo (y que vuelve a mostrar la debilidad del formato de respuesta), debo asegurarme de que el tipo de la respuesta sea la esperada. Por ejemplo, si todo hubiese ido bien, no hubiera recibido un tipo MensajeDeError, si no un tipo negociositem… lo cual es incómodo para testear y trabajar con esta api (pero es bueno para reducir el consumo de tráfico ya que devuelve solo lo que necesitas.</span></span></p> <p><span style="background: white; color: black"><span style="background: white; color: black">A partir de aquí, se me habré el horizonte de poder probar como si estuviera enviando peticiones a la API como cualquier otra APP, y pudiendo hacer test casi de integración.</span></span></p> <p><span style="background: white; color: black"><span style="background: white; color: black">Espero que sea de utilidad para alguien.</span></span></p> <p><span style="background: white; color: black"><span style="background: white; color: black"></span></span> </p> <p><span style="background: white; color: black"><span style="background: white; color: black"></span></span> </p> <p><span style="background: white; color: black"></span></p> Juan Quijanohttp://www.blogger.com/profile/10969229495916572526noreply@blogger.com2