代码之家  ›  专栏  ›  技术社区  ›  Jay Haase

单元测试使用nslocalizedstring的iPhone代码

  •  16
  • Jay Haase  · 技术社区  · 14 年前

    我有一个使用本地化字符串的iPhoneIOS4.1应用程序。我刚刚开始使用SentingKit构建单元测试。我已经成功地测试了许多不同类型的值。

    我无法正确测试任何使用nslocalizedstring调用的代码,因为当代码在我的logictests目标中运行时,所有nslocalizedstring调用只返回字符串键。

    我已将可本地化的.strings文件添加到logictests目标。

    我的问题是:我必须如何配置我的logictests目标,以便调用nslocalizedstring将返回本地化字符串而不是字符串键。

    7 回复  |  直到 7 年前
        1
  •  10
  •   Mikhail Grebionkin    7 年前

    这个问题把我逼疯了,但我能 NSLocalizedString 行为举止。

    Zoul是对的,如果您在逻辑测试中将MainBundle打印到控制台,那么包含可本地化.strings文件的包就不同了。你需要有条件地重新定义 n本地化字符串 无论何时运行单元测试。我是通过以下步骤完成的:

    1. 我们需要一种方法来告诉我们什么时候在逻辑测试目标中,所以在逻辑测试目标中添加类似逻辑测试的东西。 Preprocessor Macros 生成设置。
    2. 我的代码中只有一个地方需要重新定义 n本地化字符串 ,因此我可以将以下代码放在与该类对应的头中。如果您在多个地方遇到此问题,我建议将以下代码放在头中,然后 #include -在您需要的地方使用它(我尝试使用.pch文件,但它在逻辑测试中不起作用)。无论如何,把这个放在使用的类的头上 n本地化字符串 :

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

    更换 YOUR_IDENTIFIER 包含应用程序包的包标识符(可在 Info.plist 文件,密钥为 CFBundleIdentifier )这假设您已经定义了 LOGIC_TESTS 作为预处理器宏 只有 在您的逻辑测试目标中。

    编辑: 奇怪的是,一旦我删除了一些调试代码,这个解决方案就停止工作了。看起来您还必须欺骗Xcode来加载包。它的作用如下:

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

    在哪里? path_to_main_bundle == [[NSBundle mainBundle] bundlePath] 当你运行你的主要目标。只需在gdb中记录一次或使用 NSLog 在您的应用程序上,委派代表获取路径。它应该看起来像 /Users/YOUR_USER_NAME/Library/Application Support/iPhone Simulator/4.1/Applications/UUID_LOTS_OF_LETTERS_AND_NUMBERS_HERE/App.app .

    我把代码放在我的一个逻辑测试类的安装调用中。不,我不知道为什么我必须记录所有的包才能使它工作,所以任何有线索的人,请告诉我!

        2
  •  7
  •   cpungaliya    13 年前

    我可以在单元测试设置中使用以下代码来使用nslocalizedstring

    - (void)setUp
    {
        [super setUp];
    
        NSString *bundlePath = [[NSBundle bundleForClass:[self class]] resourcePath];
        [NSBundle bundleWithPath:bundlePath];
    }
    
        3
  •  4
  •   smilingpoplar    13 年前

    我遇到了同样的问题,谢谢@kevboth,我通过在 yourunittests-prefix.pch :

    #undef NSLocalizedString
    #define NSLocalizedString(key, comment) [[NSBundle bundleForClass:[self class]] localizedStringForKey:(key) value:@"" table:nil]
    
        4
  •  2
  •   GatoCurioso    9 年前

    快捷方式: 这是一个简单的版本,可以扩展到不同的用例(例如使用表名)。

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

    这个全局方法可以放在一个.swift文件中,也可以放在类范围之外的其他地方。 这样使用:

    NSLocalizedString("YOUR-KEY", referenceClass: self)
    
        5
  •  1
  •   zoul    14 年前

    也许吧 NSLocalizedString 只在应用程序测试中工作吗?这是一个调用 localizedStringForKey:value:table: 在主捆上。也许吧 +[NSBundle mainBundle] 返回测试目标中不确定的内容?

        6
  •  0
  •   Cris    12 年前

    在我看来,最干净的解决方案似乎包括 Localizable.strings 在你的第八个包裹里。

        7
  •  0
  •   juliancadi    7 年前

    Swift 4.1-Xcode 9.3

    可本地化字符串(en)

    "TEXT_TO_LOCALIZE" = "Hello!";
    

    可本地化的.strings

    "TEXT_TO_LOCALIZE" = "Hola!";
    

    Xctestcase测试用例

    class AppTestCase: XCTestCase {
       func testLocalize() {
          let localizedText = "TEXT_TO_LOCALIZE".localized(for: reference)
          print(localizedText) // "Hello!" or "Hola!"
       }
    }
    
    extension String {
       public func localized(for aClass: AnyClass) -> String {
          let bundle = Bundle(for: aClass)
          return NSLocalizedString(self, tableName: nil, bundle: bundle, comment: "")
       }
    }
    
    extension XCTestCase {
       var reference: AnyClass {
          return type(of: self)
       }
    }