2010-09-30 16 views
14

Tengo una aplicación iPhone iOS4.1 que utiliza cadenas localizadas. Acabo de comenzar a construir pruebas unitarias usando SenTestingKit. He podido probar con éxito diferentes tipos de valores.Unit Testing iPhone Code que usa NSLocalizedString

No puedo probar correctamente ninguno de mis códigos que usa llamadas NSLocalizedString, porque cuando el código se ejecuta en mi destino LogicTests, todas mis llamadas NSLocalizedString solo devuelven la clave de cadena.

He agregado mi archivo Localizable.strings al destino LogicTests.

Mi pregunta es: ¿cómo debo configurar mi destino LogicTests para que las llamadas a NSLocalizedString devolverán la cadena localizada y no la clave de cadena.

Respuesta

9

Este problema me estaba volviendo loco, pero pude obtener NSLocalizedString para comportarse.

zoul tenía razón, si imprime el paquete principal en la consola en una prueba lógica, no es el mismo paquete que contiene su archivo Localizable.strings. Necesita redefinir condicionalmente NSLocalizedString siempre que ejecute las pruebas de su unidad. Lo hice en los siguientes pasos:

  1. Necesitamos una forma de saber cuando estamos en nuestro objetivo de las pruebas de lógica, por lo que añadir algo como LOGIC_TESTS al ajuste Preprocessor Macros construir su pruebas lógicas de destino.
  2. Sólo hay 1 lugar en mi código donde necesito redefinir NSLocalizedString, así que pude colocar el siguiente código en el encabezado correspondiente a esa clase. Si tienes este problema en varios lugares, te sugiero que pongas el siguiente código en un encabezado y #include, donde sea que lo necesites (traté de usar un archivo .pch pero no funciona en las pruebas lógicas). De todos modos, colocar esto en alguna parte en la cabecera de la clase (s) que utilizan NSLocalizedString:

    #ifdef LOGIC_TESTS 
    #undef NSLocalizedString 
    #define NSLocalizedString(key, comment) [[NSBundle bundleWithIdentifier:@"YOUR_IDENTIFIER"] localizedStringForKey:(key) value:@"" table:nil] 
    #endif 
    

Reemplazar YOUR_IDENTIFIER con el paquete identificador de paquete de la aplicación (que se encuentra en su archivo Info.plist, clave es CFBundleIdentifier). Esto asume que ha definido LOGIC_TESTS como macro del preprocesador solo en su objetivo de Pruebas lógicas.

editar: Curiosamente, una vez que eliminé algún código de depuración, esta solución dejó de funcionar. Parece que tienes que engañar a Xcode para que cargue el paquete también. A continuación se hace:

NSString *path = @"path_to_main_bundle"; 
NSBundle *bundle = [NSBundle bundleWithPath:path]; 
NSLog(@"bundles: %@", [NSBundle allBundles]); 

Dónde path_to_main_bundle es == [[NSBundle mainBundle] bundlePath] al ejecutar su principal objetivo. Simplemente inicie sesión una vez en gdb o use NSLog en su delegado de la aplicación para tomar la ruta. Debería verse como /Users/YOUR_USER_NAME/Library/Application Support/iPhone Simulator/4.1/Applications/UUID_LOTS_OF_LETTERS_AND_NUMBERS_HERE/App.app.

Coloqué ese código en la llamada setUp para una de mis clases de prueba lógica. Y no, no tengo idea de por qué tengo que registrar todos los paquetes para que funcione, por lo que cualquier persona que tenga una pista, ¡por favor hágamelo saber!

+0

Tiene que haber una forma más elegante de hacerlo, pero tengo otras cosas en las que necesito trabajar. Sospecho que la verdadera solución es encontrar una manera de localizar los recursos del paquete sin una extraña codificación e introspección. – kevboh

+0

¡Amigo! Gracias por una respuesta tan detallada. Esto será de gran ayuda. Me sorprende que haya pocas personas que parezcan haber encontrado esto, tal vez no muchas personas que localizan la prueba unitaria. ;-) –

+0

No hay problema. Sí, es extraño cómo no pude encontrar nada sobre este problema en el interwebs. Definitivamente déjame saber si descubres algo más sobre esto. – kevboh

1

¿Tal vez NSLocalizedString solo funcionará dentro de las pruebas de aplicación? Esta es una macro que invoca localizedStringForKey:value:table: en el paquete principal. Tal vez +[NSBundle mainBundle] devuelve algo dudoso en el objetivo de prueba?

+0

Creo que usted es uno de algo, estoy bastante seguro de las pruebas lógicas utilizan un paquete diferente, entonces el haz principal. –

+0

Esto! Probado con Xcode 4.4 – Grav

4

me encuentro con el mismo problema, y ​​gracias @kevboth abordo mediante la adición de dos líneas para YourUnitTests-Prefix.pch:

#undef NSLocalizedString 
#define NSLocalizedString(key, comment) [[NSBundle bundleForClass:[self class]] localizedStringForKey:(key) value:@"" table:nil] 
+0

La mejor respuesta en mi humilde opinión. –

+0

A tener en cuenta: #undef NSLocalizedStringWithDefaultValue #define NSLocalizedStringWithDefaultValue (clave, TBL, paquete, val, comentario) [[NSBundle bundleForClass: [clase de auto]] localizedStringForKey: (clave) Valor: (val) tabla: (TBL)] –

7

pude usar NSLocalizedString usando el siguiente código en la configuración de mi unidad de prueba

- (void)setUp 
{ 
    [super setUp]; 

    NSString *bundlePath = [[NSBundle bundleForClass:[self class]] resourcePath]; 
    [NSBundle bundleWithPath:bundlePath]; 
} 
+0

Esto funcionó muy bien para mí, ¡gracias por compartir! El uso de NSLocalizedStrings parece funcionar automáticamente cuando la unidad prueba cargar el paquete de aplicaciones principal (configuración del cargador de paquetes). –

+0

¡Gracias, estoy usando GHUnit funcionó para mí! – Denis

0

la solución más limpia, me parece justo para incluir un Localizable.strings en su paquete octest.

+2

Traté de agregar en mi objetivo de prueba, pero no funcionó. –

1

un acceso directo para Swift: Esta es una versión simple que se puede extender a diferentes casos de uso (por ejemplo, con el uso de nombres de tablas).

public func NSLocalizedString(key: String, referenceClass:AnyClass) -> String 
{ 
    let bundle = NSBundle(forClass: referenceClass) 
    return NSLocalizedString(key, tableName:nil, bundle: bundle, comment: "") 
} 

Este método global se puede colocar en un solo archivo .swift o en otro lugar fuera del alcance de la clase. utilizar de esta manera:

NSLocalizedString("YOUR-KEY", referenceClass: self) 
+1

¡Impresionante! Trabajó para mi ! No se olvide de agregar .strings-File en su Membresía Target. –