2010-09-30 35 views
14

Tôi có ứng dụng iPhone iOS4.1 sử dụng các chuỗi được bản địa hóa. Tôi vừa bắt đầu xây dựng các bài kiểm tra đơn vị bằng cách sử dụng SenTestingKit. Tôi đã có thể thử nghiệm thành công nhiều loại giá trị khác nhau.Kiểm tra đơn vị Mã iPhone Sử dụng NSLocalizedString

Tôi không thể kiểm tra chính xác bất kỳ mã nào sử dụng lệnh NSLocalizedString, vì khi mã chạy trong mục tiêu LogicTests của tôi, tất cả lệnh gọi NSLocalizedString của tôi chỉ trả về khóa chuỗi.

Tôi đã thêm tệp Localizable.strings của mình vào mục tiêu LogicTests.

Câu hỏi của tôi là: Làm cách nào tôi phải định cấu hình mục tiêu LogicTests của mình để các cuộc gọi tới NSLocalizedString sẽ trả về chuỗi được bản địa hóa chứ không phải chuỗi khóa.

Trả lời

9

Sự cố này khiến tôi phát điên, nhưng tôi có thể nhận được NSLocalizedString để hoạt động.

zoul đã đúng, nếu bạn in mainBundle vào bảng điều khiển trong kiểm tra logic, nó không phải là cùng một gói chứa tệp Localizable.strings của bạn. Bạn cần định nghĩa lại điều kiện NSLocalizedString bất cứ khi nào bạn chạy thử nghiệm đơn vị của mình. Tôi đã làm điều đó trong các bước sau:

  1. Chúng ta cần một cách để biết khi nào chúng tôi trong mục tiêu kiểm tra logic của chúng tôi, vì vậy thêm một cái gì đó giống như LOGIC_TESTS để Preprocessor Macros xây dựng thiết lập kiểm tra logic mục tiêu của bạn.
  2. Chỉ có 1 vị trí trong mã của tôi nơi tôi cần xác định lại NSLocalizedString, vì vậy tôi có thể đặt mã sau vào tiêu đề tương ứng với lớp đó. Nếu bạn gặp vấn đề này ở nhiều nơi, tôi khuyên bạn nên đặt mã sau vào tiêu đề và #include -nhấn vào nơi bạn cần (tôi đã thử sử dụng tệp .pch nhưng không hoạt động trong Kiểm tra logic). Dù sao, đặt một nơi nào đó trong tiêu đề của lớp (es) mà sử dụng NSLocalizedString:

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

Thay YOUR_IDENTIFIER với Bundle Định danh của gói ứng dụng của bạn (tìm thấy trong tập tin Info.plist của bạn, quan trọng là CFBundleIdentifier). Điều này giả định rằng bạn đã xác định LOGIC_TESTS làm macro tiền xử lý chỉ trong mục tiêu Kiểm tra logic của bạn.

chỉnh sửa: Thật kỳ lạ, khi tôi xóa một số mã gỡ lỗi giải pháp này đã ngừng hoạt động. Dường như bạn cũng phải lừa Xcode để tải gói. Sau đây làm nó:

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

đâu path_to_main_bundle== [[NSBundle mainBundle] bundlePath] khi bạn chạy mục tiêu chính của bạn. Chỉ cần đăng nhập nó một lần trong gdb hoặc sử dụng NSLog trên đại biểu ứng dụng của bạn để lấy đường dẫn. Nó sẽ trông giống như /Users/YOUR_USER_NAME/Library/Application Support/iPhone Simulator/4.1/Applications/UUID_LOTS_OF_LETTERS_AND_NUMBERS_HERE/App.app.

Tôi đã đặt mã đó trong cuộc gọi thiết lập cho một trong các lớp kiểm tra logic của tôi. Và không, tôi không có ý tưởng tại sao tôi phải đăng nhập allBundles để làm cho nó hoạt động, vì vậy bất cứ ai có một đầu mối, xin vui lòng cho tôi biết!

+0

Phải có một cách duyên dáng hơn để thực hiện việc này, nhưng tôi có những thứ khác mà tôi cần phải thực hiện. Tôi nghi ngờ việc sửa chữa thực sự là tìm cách để xác định vị trí các tài nguyên bó mà không gặp khó khăn và khó hiểu. – kevboh

+0

Dude! Cảm ơn một câu trả lời chi tiết như vậy. Đây sẽ là một trợ giúp lớn. Tôi ngạc nhiên vì vậy rất ít người dường như đã gặp phải điều này - có thể không có nhiều người địa phương hóa thử nghiệm đơn vị. ;-) –

+0

Không sao cả. Vâng, thật kỳ lạ khi tôi không thể tìm thấy bất cứ điều gì về vấn đề này trong interwebs. Chắc chắn cho tôi biết nếu bạn tìm ra bất cứ điều gì khác về điều này. – kevboh

1

Có thể NSLocalizedString sẽ chỉ hoạt động trong các thử nghiệm ứng dụng? Đây là macro gọi số localizedStringForKey:value:table: trên gói chính. Có lẽ +[NSBundle mainBundle] trả về một thứ gì đó trong mục tiêu thử nghiệm?

+0

Tôi nghĩ rằng bạn là một trong những thứ, tôi khá chắc chắn các bài kiểm tra logic sử dụng một gói khác nhau sau đó gói chính. –

+0

Điều này! Thử nghiệm với Xcode 4.4 – Grav

4

tôi gặp phải cùng một vấn đề, và, nhờ @kevboth, tôi giải quyết nó bằng cách thêm hai dòng để YourUnitTests-Prefix.pch:

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

Câu trả lời hay nhất IMHO. –

+0

Worth chú ý: #undef NSLocalizedStringWithDefaultValue #define NSLocalizedStringWithDefaultValue (key, tbl, bó, val, bình luận) [[NSBundle bundleForClass: [tự lớp]] localizedStringForKey: giá trị (key): (val) Bảng: (tbl)] –

7

tôi đã có thể sử dụng NSLocalizedString sử dụng đoạn mã sau vào thiết lập cho thử nghiệm đơn vị của tôi

- (void)setUp 
{ 
    [super setUp]; 

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

Điều này làm việc tuyệt vời cho tôi, cảm ơn bạn đã chia sẻ! Sử dụng NSLocalizedStrings dường như tự động hoạt động khi kiểm tra đơn vị tải gói ứng dụng chính (thiết lập trình tải gói). –

+0

Cảm ơn bạn, tôi đang sử dụng GHUnit đã làm việc cho tôi! – Denis

0

Giải pháp sạch nhất dường như với tôi chỉ bao gồm Localizable.strings trong gói octest của bạn.

+2

Tôi đã cố gắng thêm vào mục tiêu thử nghiệm của mình nhưng không hoạt động. –

1

Phím tắt cho Swift: Đây là phiên bản đơn giản có thể được mở rộng đến các trường hợp sử dụng khác nhau (ví dụ: với việc sử dụng tableNames).

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

Phương thức toàn cục này có thể được đặt trong một tệp .swift đơn lẻ hoặc một nơi khác ngoài phạm vi lớp học. Sử dụng nó như thế này:

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

Tuyệt vời! Đã làm cho tôi ! Đừng quên thêm các .strings-File vào thành viên mục tiêu của bạn. –

Các vấn đề liên quan