I have an iPhone iOS4.1 application that uses localized strings. I have just started building unit tests using the SenTestingKit. I have been able to successfully test many different types of values.
I am unable to correctly test any of my code that uses NSLocalizedString calls, because when the code runs in my LogicTests target, all of my NSLocalizedString calls only return the string key.
I have added my Localizable.strings file to the LogicTests target.
My question is: How must I configure my LogicTests target so that calls to NSLocalizedString will return the localized string and not the string key.
This problem was driving me crazy, but I was able to get NSLocalizedString
to behave.
zoul was right, if you print the mainBundle to the console in a logic test, it's not the same bundle that contains your Localizable.strings file. You need to conditionally redefine NSLocalizedString
whenever you run your unit tests. I did it in the following steps:
Preprocessor Macros
build setting.There's only 1 place in my code where I need to redefine NSLocalizedString
, so I was able to place the following code in the header corresponding to that class. If you're having this problem in multiple places, I'd suggest putting the following code in a header and #include
-ing it where you need it (I tried using a .pch file but it doesn't work in Logic Tests). Anyway, place this somewhere in the header of class(es) that use NSLocalizedString
:
#ifdef LOGIC_TESTS
#undef NSLocalizedString
#define NSLocalizedString(key, comment) [[NSBundle bundleWithIdentifier:@"YOUR_IDENTIFIER"] localizedStringForKey:(key) value:@"" table:nil]
#endif
Replace YOUR_IDENTIFIER
with the Bundle Identifier of your app's bundle (found in your Info.plist
file, key is CFBundleIdentifier
). This assumes that you've defined LOGIC_TESTS
as a preprocessor macro only in your Logic Tests target.
edit: Curiously, once I removed some debugging code this solution stopped working. It looks like you have to trick Xcode into loading the bundle as well. The following does it:
NSString *path = @"path_to_main_bundle";
NSBundle *bundle = [NSBundle bundleWithPath:path];
NSLog(@"bundles: %@", [NSBundle allBundles]);
Where path_to_main_bundle
is == [[NSBundle mainBundle] bundlePath]
when you run your main target. Just log it once in gdb or using NSLog
on your app delegate to grab the path. It should look something like /Users/YOUR_USER_NAME/Library/Application Support/iPhone Simulator/4.1/Applications/UUID_LOTS_OF_LETTERS_AND_NUMBERS_HERE/App.app
.
I placed that code in the setUp call for one of my logic test classes. And no, I have no idea why I have to log allBundles to make it work, so anyone who has a clue, please let me know!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With