No sé si ustedes hayan notado el mes pasado (con todas las fiestas que había) que el equipo de Visual Studio anuncio el paquete de SharePoint Emulators de Visual Studio 2012 para SharePoint 2010.
De entrada este paquete solo aplica para SharePoint 2010 y utilizándolo en Visual Studio 2012. Es comprensible que este paquete solo aplique para SharePoint 2010, dado el poco tiempo que lleva SharePoint 2013 liberado, además de que la finalidad del emulador es poder probar código de servidor, mismo que Microsoft desalienta escribir para SharePoint 2013.
Este paquete se puede instalar a través de NuGet. Solo tienen que buscarlo y aparece dentro de los resultados.
En el pasado había sido bastante difícil aislar los componentes SharePoint de una solución para realizar pruebas unitarias, debido a que estos componentes dependen enormemente de SharePoint, es decir, para poder realizar la ejecución de pruebas de esos componentes era necesario tener instalado SharePoint.
SharePoint Emulators Package nos permite crear pruebas unitarias y ejecutarlas sin tener instalado un ambiente de SharePoint, este paquete se basa en el concepto de Shims de Microsoft Fakes para crear un contexto (un conjunto de Shims) en memoria de los objetos más comunes dentro de la API de SharePoint. Con lo que, para crear una prueba unitaria que utiliza objetos de la API de SharePoint lo único que debe hacer es encerrar el código que estamos probando dentro de un SharePoint Emulator Scope.
[TestMethod] public void CreateList() { using (SharePointEmulationScope scope = new SharePointEmulationScope(Microsoft.QualityTools.Testing.Emulators.EmulationMode.Enabled)) { using (SPSite site = new SPSite("http://UrldePrueba/")) { using (SPWeb web = site.OpenWeb()) { Assert.IsNotNull(web); //Definiendo la lista Guid listId = site.RootWeb.Lists.Add(listName, listName, SPListTemplateType.GenericList); SPList list = site.RootWeb.Lists[listId]; Assert.IsNotNull(list); Assert.AreEqual(list.Title, listName, "Bad list name!"); //agregando los campos a la lista list.Fields.Add("Code", SPFieldType.Number, true); list.Fields.Add("Name", SPFieldType.Text, true); list.Fields.Add("Description", SPFieldType.Text, true); //agregando dos nuevos elemento a la lista SPListItem item1 = list.Items.Add(); item1["Code"] = 1; item1["Name"] = "West"; item1["Description"] = "West Region"; item1.Update(); SPListItem item2 = list.Items.Add(); item2["Code"] = 1; item2["Name"] = "East"; item2["Description"] = "East Region"; item2.Update(); Assert.AreEqual(list.ItemCount, 2, "Bad number of items"); } } } }
Como mencionaba antes, este paquete solo contiene los Shims para los objetos de uso más común dentro de la API de SharePoint, por lo que habrá casos es los que al hacer uso de ciertos métodos o propiedades, que devuelven un tipo de objeto que no tiene su correspondiente Shim dentro del emulador, obtendremos excepciones de tipo NotSupportedException, como por ejemplo al intentar utilizar el método GetItems de un objeto SPList, que devuelve un objeto de tipo SPListItemCollection.
El siguiente código muestra el método que se está probando, en la línea 17 está la llamada al método GetItems que lanzará la excepción.
public string GetNameByCode(string listName, SPWeb web, int code) { SPList list = web.Lists[listName]; var listQuery = new SPQuery { Query = String.Format( "" + " ", code) }; string name = string.Empty; foreach (SPListItem item in list.GetItems(listQuery)) { name = item["Name"].ToString(); } return name; }" + " " + "" + " {0} " + "
Lo genial de esto, es que es posible inyectar Shims al Emulador para los tipos no soportados, como por ejemplo para SPListItemCollection, de la forma tradicional, es decir usando Shims, como se aprecia de las líneas 41 a la 50
[TestMethod] public void SearchItemById() { int searchById = 2; using (SharePointEmulationScope scope = new SharePointEmulationScope(Microsoft.QualityTools.Testing.Emulators.EmulationMode.Enabled)) { using (SPSite site = new SPSite("http://UrldePrueba/")) { using (SPWeb web = site.OpenWeb()) { Assert.IsNotNull(web); //Definiendo la lista Guid listId = site.RootWeb.Lists.Add(listName, listName, SPListTemplateType.GenericList); SPList list = site.RootWeb.Lists[listId]; Assert.IsNotNull(list); Assert.AreEqual(list.Title, listName, "Bad list name!"); //agregando los campos a la lista list.Fields.Add("Code", SPFieldType.Number, true); list.Fields.Add("Name", SPFieldType.Text, true); list.Fields.Add("Description", SPFieldType.Text, true); //agregando dos nuevos elemento a la lista SPListItem item1 = list.Items.Add(); item1["Code"] = 1; item1["Name"] = "West"; item1["Description"] = "West Region"; item1.Update(); SPListItem item2 = list.Items.Add(); item2["Code"] = 2; item2["Name"] = "East"; item2["Description"] = "East Region"; item2.Update(); Assert.AreEqual(list.ItemCount, 2, "Bad number of items"); //Agregamos el Shimp para el objeto SPListItemCollection if (scope.EmulationMode == EmulationMode.Enabled) { var fakeList = new ShimSPList(list); fakeList.GetItemsSPQuery = (query) => { var shim = new ShimSPListItemCollection(); shim.Bind(new[] { list.Items[0], list.Items[1] }); return shim.Instance; }; } RegionGateway gateway = new RegionGateway(); //Ahora al realizar la llamada al metodo GetNameByCode, no se lanzara la excepcion string result = gateway.GetNameByCode(listName, site.RootWeb, searchById); Assert.AreNotEqual(string.Empty, result, true, "Search Failed!"); Region searchItem = gateway.GetRegionById(listName, web, 1); Assert.IsNotNull(searchItem); Assert.AreEqual("West", searchItem.Name, true); } } } }
Sin duda alguna un importante paquete que debiéramos usar desde ya para las pruebas unitarias de nuestro código. Ahora lo importante sería preguntar para cuando este paquete estará disponible para SharePoint 2013.
Por último les comparto el proyecto de Visual Studio para que vean el código y puedan analizarlo mejor.
Referencias
- Using emulators to isolate unit tests for Sharepoint 2010 applications
- Introducing SharePoint Emulators
- Isolating Code under Test with Microsoft Fakes
- Using shims to isolate your application from other assemblies for unit testing
Happy Code!
0 comentarios:
Publicar un comentario