2012-06-01 8 views
10

Estoy tratando de burlarme de una hoja de cálculo de Excel usando NSubstitute u otro marco de burla y MSTest (Visual Studio 2010). No estoy seguro de si hay una manera mejor que esto - y esto no funciona bien para las pruebas:¿Cómo evito el uso dinámico cuando me burlo de una hoja de cálculo Excel?

He aquí un ejemplo (esto es todo el código prototipo de este momento, y no muy limpio):

int[] lowerBounds = { 1, 1 }; 
int[] lengths = { 2, 2 }; 

//Initialize a 1-based array like Excel does: 
object[,] values = (object[,])Array.CreateInstance(typeof(object), lengths, lowerBounds); 
values[1,1] = "hello"; 
values[2,1] = "world";  

//Mock the UsedRange.Value2 property 
sheet.UsedRange.Value2.Returns(values); 

//Test: 
GetSetting(sheet, "hello").Should().Be("world"); //FluentAssertions 

Hasta ahora, todo bien: esto pasa si el método GetSetting es en el mismo proyecto como mi prueba. Sin embargo, cuando GetSetting está en mi proyecto VSTO Excel-Addin, se produce el siguiente error en la primera línea de la función GetSetting:

System.MissingMethodException: Error: Missing method 'instance object [MyExcel.AddIn] Microsoft.Office.Interop.Excel.Range::get_Value2()' from class 'Castle.Proxies.RangeProxy'. 

Como referencia, el GetSetting agarra un valor de columna en la hoja, y vuelve el valor en el columnB.

public static string GetSetting(Excel.Worksheet sheet, string settingName) { 
    object[,] value = sheet.UsedRange.Value2 as object[,]; 
    for (int row = 1; row <= value.GetLength(1); row++) { 
    if (value[1, row].ToString() == settingName) 
     return value[2, row].ToString(); 
    } 
    return ""; 
} 

La pieza final interesante es si redefino la firma de mi método de la siguiente manera:
GetSetting public static string (dinámica hoja, cuerda SettingName)
funciona en el proyecto VSTO.

¿Qué está pasando y cuál es la mejor manera de hacer algo como esto?

Gracias!

+1

Esto suena como un caso de referencias faltantes de alguna manera. –

+1

Cuando ejecuta sus pruebas, ¿está microsoft.office.tools.excel.dll en el directorio bin? – mayu

+0

En mi caso, al desactivar "Insertar tipos de interoperabilidad" y activar "Copiar local" para el archivo DLL en mi proyecto de prueba (Microsoft.Office.Interop.Word en mi caso) se solucionó el error. Gracias. –

Respuesta

3

La actualización VS2012:Moq & Interop Types: works in VS2012, fails in VS2010?

Primero: Algo ha cambiado:How do I avoid using dynamic when mocking an Excel.worksheet?

me encontré con el mismo problema que imita objetos de Excel usando NSubstitute. La dinámica resolvió el problema tal como lo mencionas. Sin embargo, quería encontrar la causa raíz.


cuando el proyecto tiene una referencia a Microsoft.Office.Interop.Excel.Extensions.dll es necesario comprobar si los tipos de propiedad Insertar interoperabilidad es visible. Si es eso, significa que su objetivo es .Net 4.0 (que podría adivinar a partir de la palabra clave dinámica).

Puede dejar el Proyecto de prueba orientado a .Net 4.0 pero necesita cambiar de nuevo el marco .Net de VSTO Project a 3.5. Después se le probable que tenga que hacer algo de conversión explícita y totalmente calificar cosas que deshacerse de estos errores:

C# "objeto no contiene definición de" Office Excel interoperabilidad errores, aquí hay un par de ejemplos:

.Net 4.0:

if (tmpsheetName == xlApp.ActiveSheet.Name) 

.Net 3.5 equivalente

Worksheet activeSheet = (Worksheet)xlApp.ActiveSheet; 
if (tmpsheetName == activeSheet.Name) 

Otro ejemplo:

rn.Select(); 

.Net 4,0

xlApp.Selection.HorizontalAlignment = Constants.xlCenter; 
xlApp.Selection.Font.Bold = true; 
xlApp.Selection.Merge(); 

.Net 3.5 equivalente

rn.HorizontalAlignment = Constants.xlCenter; 
rn.Font.Bold = true; 
rn.Merge(); 

Proceda a reparar todos los errores de sintaxis de .Net 3.5 vs 4.0 según los ejemplos anteriores. No olvides eliminar el tipo de parámetro dynamic y reemplazarlo por el Worksheet original. ¡Finalmente, vuelve a encender la Prueba y pasará!

Teniendo en cuenta todo el dolor que he experimentado con Microsoft.CSharp.DLL en este thread Soy de la opinión de pruebas VSTO .Net 4.0 burlando de proyectos con marcos no funciona.

+0

¡Gracias por compartir tu experiencia y solución! ¡Realmente lo aprecio! ¿Cómo es el rendimiento en las pruebas? – tony722

+0

@ tony722, consulte la actualización VS2012. Gracias. –

+0

Muy interesante. ¡¡Gracias por la actualización!! ¡Ahora solo necesito la actualización de VS2012! – tony722

-2

Resulta que burlarse de objetos de interoperabilidad COM muy complejos como el objeto Excel o el objeto InDesign utilizando cualquiera de los frameworks basados ​​en castle (nsubstitute, ninject, etc.), no proporciona suficiente arranque de rendimiento. Los tiempos de ejecución para las pruebas aún se pueden medir en segundos. (Multiplicar eso por decenas o cientos de pruebas hace que las pruebas unitarias sigan siendo demasiado lentas para ejecutarse bajo los principios de prueba de TDD constantemente).

Probar la lógica de Excel debe considerarse una prueba de integración y, como tal, correr contra el el objeto real de Excel debería estar bien, haciendo burla no muy útil en tal escenario. Los resultados serán pruebas mucho más útiles contra un objeto real.

La prueba de una capa de abstracción colocada entre Excel y la aplicación permitiría probar rápidamente la lógica de la aplicación. Y probar la capa de abstracción a excel en las pruebas de integración debería ser suficiente para probar la aplicación a fondo.

+0

Esto no responde la pregunta. Solo da una hipótesis interesante basada en la experiencia del usuario. Sin muestra de código, la otra respuesta debería haber sido aceptada. –

Cuestiones relacionadas