Mock
Ê×ÏÈ¿ÆÆÕÏÂʲôÊÇmock²âÊÔ¡£mock²âÊÔÊǸöºÜÉñÆæ¶øÓֺܿáµÄ¼¼Êõ£¬ÔÚ²âÊÔ¹ý³ÌÖУ¬¶ÔÓÚһЩ²»ÈÝÒ×¹¹Ôì»ò²»ÈÝÒ×»ñÈ¡µÄ¶ÔÏ󣬴ËʱÄã¿ÉÒÔ´´½¨Ò»¸öÐéÄâµÄ¶ÔÏó£¨mock
object£©À´Íê³É²âÊÔ¡£
ÀýÈçÄã¿ÉÄÜÒª³¢ÊÔ100´Î²Å»á·µ»ØÒ»¸öNSError£¬Í¨¹ýmock objectÄã¿ÉÒÔ×ÔÐд´½¨Ò»¸öNSError¶ÔÏ󣬲âÊÔÔÚ³ö´íÇé¿öϳÌÐòµÄ´¦ÀíÊÇ·ñ·ûºÏÄãµÄÔ¤ÆÚ¡£
ÀýÈçÄãÒªÁ¬½Ó·þÎñÆ÷µ«ÊÇ·þÎñÆ÷ÔÚʵÑéÊÒ£¬ÄãÔÚÍ⹤×÷µÄʱºò¾ÍÎÞ·¨²âÊÔÁË£¨Ð¡µÜ¾ÍÊÔ¹ýÕâÖÖÇé¿ö£¬·Ç³£·´¸Ð£©£¬Õâ¸öʱºòÄã¿ÉÒÔ´´½¨Ò»¸öÐéÄâµÄ·þÎñÆ÷£¬²¢·µ»ØÒ»Ð©ÄãÖ¸¶¨µÄÊý¾Ý£¬´Ó¶øÈƹý·þÎñÆ÷¡£
ÀýÈç¼ÙÉèÄãÒª·ÃÎÊÒ»¸öÊý¾Ý¿â£¬µ«ÊÇ·ÃÎʹý³ÌµÄ¿ªÏú¾Þ´ó£¬ÕâʱÄã¿ÉÒÔÐéÄâÒ»¸öÊý¾Ý¿â£¬²¢ÇÒ·µ»ØÒ»Ð©×ÔÐж¨ÖƵÄÊý¾Ý£¬´Ó¶øÈƹýÁËÊý¾Ý¿âµÄ·ÃÎÊ¡£
mockµÄ˼ÏëºÜ¼òµ¥£ºÃ»ÓÐÌõ¼þ£¿ÎÒÃǾÍ×ÔÐд´ÔìÌõ¼þ¡£
OCMock
1.¹ØÓÚOCMock
OCMockÊÇÒ»¸öÓÃÓÚΪiOS»òMac OS XÏîÄ¿ÅäÖÃMock²âÊԵĿªÔ´ÏîÄ¿£¬Èç¹ûÄ¿±êÊÇiOSÏîÄ¿ÄÇôÉú³ÉµÄÊǾ²Ì¬¿â£¬Èç¹ûÊÇMac
OS XÏîÄ¿Éú³ÉµÄÊÇ¿ò¼Ü¡£Ð¡µÜ´ÖÂÔ¿´¹ýÏÂOCMockµÄÔ´Â루¿Éϧ¹¦Á¦²»¹»£¬Ä¿Ç°Ö»¿´ÁËһС²¿·Ö£©£¬ÆäʵÏÖ˼Ïë¾ÍÊǸù¾ÝÒªmockµÄ¶ÔÏóµÄclassÀ´´´½¨Ò»¸ö¶ÔÓ¦µÄ¶ÔÏ󣬲¢ÇÒÉèÖúøöÔÏóµÄÊôÐԺ͵÷ÓÃÔ¤¶¨·½·¨ºóµÄ¶¯×÷£¨ÀýÈç·µ»ØÒ»¸öÖµ£¬µ÷ÓôúÂë¿é£¬·¢ËÍÏûÏ¢µÈµÈ£©£¬È»ºó½«Æä¼Ç¼µ½Ò»¸öÊý×éÖУ¬½ÓÏÂÀ´¿ª·¢ÕßÖ÷¶¯µ÷Óø÷½·¨£¬×îºó×öÒ»¸överify£¨ÑéÖ¤£©£¬´Ó¶øÅжϸ÷½·¨ÊÇ·ñ±»µ÷Ó㬻òÕßµ÷Óùý³ÌÖÐÊÇ·ñÅ׳öÒì³£µÈ¡£
ÔÚ½²½âÈçºÎÔÚiOSÏîÄ¿ÖÐÌí¼ÓOCMock¾²Ì¬¿â֮ǰ£¬Ïȸø³öOCMockµÄ×ÊÁϵØÖ·£º
OCMock¹ÙÍø
iOS Project Setup£ºÔÚiOSÏîÄ¿ÖÐÅäÖÃOCMockµÄ½Ì³Ì
erikdoe / ocmock£ºÔÚGitHubÉϵÄʾÀýÏîÄ¿£¬¿ÉÒԲο¼ÏÂÆäÖеÄһЩÅäÖòÎÊý
OCMock Download£ºOCMockµÄ¾²Ì¬¿â¡¢¿ò¼ÜºÍ¹¤³ÌÎļþ£¨¿ÉÒÔÔÚÕâÀï¿´OCMockµÄÔ´ÂëʵÏÖ£©ÏÂÔØµØÖ·£¬ÒѾ´ò°ü³Édmg¸ñʽÁË¡£
2.ÅäÖÃOCMock
ºÃ°É£¬½øÈëÖ÷Ìâ¡£»¹ÊÇÒÔ£¨Ò»£©ÖеÄUnitTestDemoÄǸö¹¤³ÌΪÀý°É¡£
1.ÏÂÔØOCMock DownloadµÄdmgÎļþ£¬½«iOSÎļþ¼ÐÖеÄÎļþ£¨libOCMock.aºÍOCMockÎļþ¼Ð£©¿½±´µ½Òª²âÊÔµÄÏîĿĿ¼Ï£º

2.´ò¿ª¹¤³Ì£¬Ê×ÏÈÌí¼ÓÒÔÉÏÎļþµ½ÏîÄ¿ÖУ¨Command + Option + A£©£º

3.´ò¿ªUnitTestDemoTests TargetµÄBuild Phases£¬Ìí¼ÓlibOCMock.aµ½ÒªÁ´½ÓµÄÀà¿âÖУº

4.´ò¿ªBuild Settings£¬ËÑË÷Other Linker Flags£¬ÉèÖÃÈçÏ£º

ÕâÀïµÄ-ObjC±íʾ¸æËßÁ´½ÓÆ÷£¬Òª°ÑOCÀàºÍCategory¼ÓÔØµ½¹¤³ÌÖУ¬µ«ÊǸÃÉèÖÃÓÐBug£¬ËùÒÔ»¹ÒªÓÃ-all_load»òÕß-force_loadÀ´¼ÓÔØ¾²Ì¬¿âÖÐûÓмÓÔØ½øÀ´µÄCategory¡£Èç¹ûʹÓÃ-all_load»á°ÑËùÓÐÏà¹ØÎ޹صÄÎļþ¶¼load½øÀ´£¬Ê¹µÃÄ¿±ê³ÌÐò±äµÃ¸ü´ó£¬ËùÒÔÓÃ-force_loadÀ´Ö¸¶¨Òª¼ÓÔØµÄ¾²Ì¬¿â¾Í¿ÉÒÔÁË£¬ÏÂÃæµÄ"$(SRCROOT)/ocmock/libOCMock.a"¾ÍÊǾ²Ì¬¿âÎļþÔÚFinderÖеÄ·¾¶¡£
ÔÙËÑË÷Header Search Paths£¬ÉèÖÃÈçÏ£º

"$(SRCROOT)/ocmock"¸ø³öµÄÊÇOCMockµÄÍ·ÎļþÔÚFinderÖеÄ·¾¶£¬Òò´Ë¸ÃÑ¡Ïî¸æËß±àÒëÆ÷Ó¦¸Ãµ½ÄÄÀïȥѰÕÒOCMock¾²Ì¬¿âµÄÍ·Îļþ¡£
3.±àдmock²âÊÔ
н¨Ò»¸ötest case classÀ࣬»ùÀàΪXCTestCase£¬ÃüÃûΪMockTableTests¡£
Ê×ÏÈÎÒÃDzâÊÔÒ»ÏÂTableDataSourceµÄnumberOfRowsInSection·½·¨ÊÇ·ñ·µ»ØÁËÕýÈ·µÄÖµ£¬²âÊÔ´úÂëÈçÏ£º
- (void)testNumberOfRows { // 1.´´½¨Table ViewµÄDataSource TableViewCellConfigureBlock cellConfigureBlock = ^(UITableViewCell *cell, NSString *item) { cell.textLabel.text = item; }; TableDataSource *tableSource = [[TableDataSource alloc] initWithItems:@[@"1", @"2", @"3"] CellIdentifier:@"foo" ConfigureCellBlock:cellConfigureBlock]; // 2.´´½¨mock table view id mockTableView = [OCMockObject mockForClass:[UITableView class]]; // 3.¶ÏÑÔ XCTAssertEqual([tableSource tableView:mockTableView numberOfRowsInSection:0],
(NSInteger)3, @"Mock table returns a bad number of rows in section 0"); } |
1.Ê×ÏÈ´´½¨data source£¬ÓÃÓÚÏÂÎÄÖе÷ÓÃnumberOfRowsInSection·½·¨¡£×¢ÒâÕâÀïTable
ViewÖеÄÄÚÈÝ@[@"1", @"2", @"3"]ÊÇÐèÒªÎÒÃÇÊÖ¶¯ÅäÖõġ£ÕâÀïÒ²ÌåÏÖÁËmockµÄÒ»¸ö¾ÖÏÞÐÔ£¬¾ÍÊÇmock
objectµÄ¹Ø¼üÊôÐÔ¶¼ÒªÎÒÃÇ×Ô¼º¶¨ÖÆ£¬Èç¹ûҪģÄâµÄ¶ÔÏó·Ç³£µÄ´ó£¬ÄÇô´´½¨Ò»¸ömock objectµÄ³É±¾½«Ô¶Ô¶´óÓÚµ¥Ôª²âÊÔ´øÀ´µÄÐ§Òæ¡£
2.Èç¹ûÒªµ¥¶À²âÊÔnumberOfRowsInSection·½·¨£¬ÎÒÃǾÍÐèÒªÓÐÒ»¸öTableView£¬Òò´ËҪͨ¹ýOCMockObjectµÄmockForClassÀà·½·¨À´´´½¨Ò»¸ömock
table view¡£
3.ͨ¹ýdata sourceµ÷Ó÷½·¨£¬²¢Ê¹ÓöÏÑÔÅжϡ£
Èç¹ûÔÚ²âÊÔʱ£¬ÎÒÃÇÖ»ÏëÔÚ¿ØÖÆÌ¨Öп´¼ûÕâ¸ö·½·¨µÄÊä³öÐÅÏ¢£¬¿ÉÒÔµã»÷·½·¨Ç°ÃæµÄÒ»¸öС²¥·Å°´Å¥£º

¿ØÖÆÌ¨Êä³ö£º
Test Suite 'Multiple Selected Tests' started at 2014-03-20 01:58:17 +0000 Test Suite 'UnitTestDemoTests.xctest' started at 2014-03-20 01:58:17 +0000 Test Suite 'CellConfigureTests' started at 2014-03-20 01:58:17 +0000 Test Suite 'CellConfigureTests' finished at 2014-03-20 01:58:17 +0000. Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'MockTableTests' started at 2014-03-20 01:58:17 +0000 Test Case '-[MockTableTests testNumberOfRows]' started. Test Case '-[MockTableTests testNumberOfRows]' passed (0.000 seconds). Test Suite 'MockTableTests' finished at 2014-03-20 01:58:17 +0000. Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'UnitTestDemoTests' started at 2014-03-20 01:58:17 +0000 Test Suite 'UnitTestDemoTests' finished at 2014-03-20 01:58:17 +0000. Executed 0 tests, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'UnitTestDemoTests.xctest' finished at 2014-03-20 01:58:17 +0000. Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.000) seconds Test Suite 'Multiple Selected Tests' finished at 2014-03-20 01:58:17 +0000. Executed 1 test, with 0 failures (0 unexpected) in 0.000 (0.001) seconds |
ÏÂÃæÀ´±àдһ¸öÉÔ΢¸´ÔÓµãµÄmock²âÊÔ£¬ÓÃÀ´²âÊÔUITableViewDataSourceÖеÄcellForRowAtIndexPath·½·¨¡£´úÂëÈçÏ£º
- (void)testCellConfiguration { // 1.´´½¨Table data source __block UITableViewCell *configuredCell = nil; __block id configuredObject = nil; TableViewCellConfigureBlock block = ^(UITableViewCell *a, id b) { configuredCell = a; configuredObject = b; }; TableDataSource *dataSource = [[TableDataSource alloc] initWithItems:@[@"a", @"b"] CellIdentifier:@"foo" ConfigureCellBlock:block]; // 2.´´½¨mock table view id mockTableView = [OCMockObject mockForClass:[UITableView class]]; // 3.É趨mock table viewµÄÐÐΪ UITableViewCell *cell = [[UITableViewCell alloc] init]; [[[mockTableView expect] andReturn:cell] dequeueReusableCellWithIdentifier:@
"foo" forIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; // [[[mockTableView stub] andReturn:cell] dequeueReusableCellWithIdentifier:@
"foo" forIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; // 4.Ö÷¶¯µ÷ÓÃcellForRowAtIndexPath·½·¨ id result = [dataSource tableView:mockTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; // 5.ÑéÖ¤mock table viewµÄÐÐΪ [mockTableView verify]; // 6.¶ÏÑÔ XCTAssertEqual(result, cell, @"Should return the dummy cell."); XCTAssertEqual(configuredCell, cell, @"This should have been passed to the block."); XCTAssertEqualObjects(configuredObject, @"a", @"This should have been passed to the block."); } |
1.´´½¨Table data source£¬ÓÃÓÚÏÂÎĵ÷ÓÃcellForRowAtIndexPath·½·¨¡£
2.´´½¨mock table view¡£
3.Èç¹ûmock table viewµ÷ÓÃÁËdequeueReusableCellWithIdentifier:@"foo"
forIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]·½·¨£¬ÄÇô¾Í·µ»ØÉÏÃæÒѾ´´½¨ºÃµÄUITableViewCell¶ÔÏó£¬expect·½·¨±íʾ¸Ã·½·¨±ØÐë±»µ÷Ó㨼û5.£©¡£
4.ͨ¹ýTable data sourceÖ÷¶¯µ÷ÓÃcellForRowAtIndexPath·½·¨£¬´Ëʱ»á´¥·¢mock
table viewµ÷ÓÃdequeueReusableCellWithIdentifier:forIndexPath:·½·¨¡£
5.×îºóÒªµ÷ÓÃverify·½·¨£¬ÓÃÓÚÑéÖ¤mock table viewµÄÐÐΪ¡£Èç¹ûmock table
viewÔÚij¸ö·½·¨Öе÷ÓÃÁËexpect£¬ÄÇô¸Ã·½·¨±ØÐëÔÚverify֮ǰ±»µ÷Ó㬷ñÔò²âÊÔÎÞ·¨Í¨¹ý¡£Èç¹ûmock
table viewµ÷ÓõÄÊÇstub£¬ÄÇôverifyʱOCMock²¢²»¹ØÐĸ÷½·¨ÊÇ·ñµ÷Óùý£¬Ö»»á¹ØÐĵ÷Óùý³ÌÊÇ·ñ·¢ÉúÒì³£»òÓвâÊÔ±»¾Ü¾øµÈ¡£
6.¶ÏÑÔ£¬ÔÚÕâÀï½øÐи÷ÖֱȽϡ£
GHUnit
¿ÉÄÜ´ó¼Ò¶¼×¢Òâµ½ÁË£¬ÔÚÔËÐвâÊԺ󣬿ØÖÆÌ¨ÖеÄÊä³ö¿ÉÒÔÓòҲ»È̶ÃÀ´ÐÎÈÝ¡£ÕâʱÎÒÃÇ¿ÉÒÔ³¢ÊÔÁíÒ»¸ö¹¤¾ß£ºGHUnit¿ò¼Ü£¬Õâ¸ö¹¤¾ßÊÇÓÐGUIµÄ¡£
Ê×Ïȸø³öһЩ²Î¿¼×ÊÁÏ£º
gh-unit / gh-unit£º¸ÃÏîÄ¿ÔÚGitHubÉϵĵØÖ·¡£
Installing in iOS (Xcode 4)£ºÔÚXcode 4ÉÏΪÏîÄ¿ÅäÖÃGHUnit£¬Ïà¶ÔXcode
5À´Ëµ¾ÉÁË£¬µ«Êǰ²×°¹ý³Ì»¹ÊÇÀàËÆµÄ¡£
guide_testing Document£º±àд²âÊԵIJο¼Îĵµ¡£
»¹ÊÇÒÔ֮ǰµÄÄǸöÏîĿΪÀý£¬½øÐÐGHUnitµÄÅäÖ㬲¢±àд»ùÓڸÿò¼ÜµÄµ¥Ôª²âÊÔ¡£
1.ÅäÖÃGHUnit
1.н¨Ò»¸öTarget£¬Ñ¡ÖпյŤ³ÌÄ£°å£º

2.Ñ¡ÖÐÄ¿±ê¹¤³ÌΪ±¾¹¤³Ì£º

½«ÐÂTargetÖеÄÈßÓàÎļþÈ«²¿É¾µô£¬°üÀ¨AppDelegate.h/.m£¬GHUnitTestsTestsÎļþ¼Ð£¬GHUnitTestsTests
TargetµÈ£¬×¢ÒâSupporting FilesºÍImages.xcassetsÒª±£Áô£º

3.´ÓGitHubÖÐÏÂÔØGHUnitÏîÄ¿£¬ÏÂÔØºó¿ÉÒÔ¿´µ½ÓиöProject-iOSĿ¼£º

È»ºó´ò¿ªÎÒÃǿɰ®µÄÖÕ¶Ë£¬Ê×ÏÈcdµ½Project-iOSĿ¼Ï£¬È»ºóÊäÈëmakeÃüÁ³É¹¦ºóµÄ²¿·ÖÌáʾÈçÏ£º
** BUILD SUCCEEDED ** BUILD_DIR="build" BUILD_STYLE="Release" sh ../Scripts/CombineLibs.sh adding: libGHUnitIOS.a (deflated 63%) sh ../Scripts/iOSFramework.sh Framework: Cleaning framework... Framework: Setting up directories... Framework: Creating symlinks... Framework: Creating library... Framework: Copying assets into current version... The framework was built at: build/Framework/GHUnitIOS.framework |
¿ÉÒÔ¿´µ½GHUnitÏîĿ·¾¶/Project-iOS/Ŀ¼Ï¶àÁ˸öbuildÎļþ¼Ð£¬./build/Framework/ÏÂÃæÉú³ÉµÄ¿ò¼Ü¾ÍÊÇÎÒÃÇmakeµÄÄ¿±ê£º

4.»Øµ½ÔÀ´µÄ¹¤³Ì£¬Command + Option + A£¬½«Éú³ÉµÄframeworkÎļþÌí¼Óµ½¹¤³ÌÖС£
´ò¿ªGHUnitTests TargetµÄBuild Settings£¬ËÑË÷Other Linker
Flags£¬½«ÆäÉèÖÃΪ-all_loadºÍ-ObjC£º

5.´ò¿ªmain.m£¬É¾³ý#import ¡°AppDelegate.h¡±
½«Ö÷º¯ÊýµÄreturnÐÞ¸ÄÈçÏ£º
return UIApplicationMain(argc, argv, nil, @"GHUnitIOSAppDelegate"); |
Íê³ÉÅäÖá£
2.±àдGHUnitµ¥Ôª²âÊÔ
ÔÚGHUnitTestsÖÐн¨Ò»¸öObjective-C Class£¬»ùÀàΪNSObject£¬ÃûΪFirstGHUnitTests¡£
½«FirstGHUnitTests.hɾ³ý£¬ÐÞ¸ÄFirstGHUnitTests.m´úÂëÈçÏ£º
#import <GHUnitIOS/GHUnit.h> #import "TableDataSource.h" #import "TableViewController.h" @interface MyTest : GHTestCase @end @implementation MyTest - (void)testStrings { NSString *string1 = @"a string"; GHTestLog(@"I can log to the GHUnit test console: %@", string1); // Assert string1 is not NULL, with no custom error description GHAssertNotNil(string1, nil); // Assert equal objects, add custom error description NSString *string2 = @"a string"; GHAssertEqualObjects(string1, string2, @"A custom error message. string1 should be equal to: %@.", string2); } - (void)testSimpleFail { GHAssertTrue(NO, nil); } - (void)testDataSourceInitializing { TableViewCellConfigureBlock cellConfigureBlock = ^(UITableViewCell *cell, NSString *item) { cell.textLabel.text = item; }; TableDataSource *tableSource = [[TableDataSource alloc] initWithItems:@[@"1", @"2", @"3"] CellIdentifier:@"TestCell" ConfigureCellBlock:cellConfigureBlock]; GHAssertNotNil(tableSource, @"TableView data source should not be nil"); } @end |
ÓÉÓÚTableDataSource.hºÍTableViewController.hÊôÓÚÁíÒ»¸öTargetÖеÄÎļþ£¬ËùÒÔÕâÀïÎÒÃÇÒª°Ñ¶ÔÓ¦µÄʵÏÖÎļþ¼ÓÈëµ½±¾TargetµÄCompile
SourcesÖУ¨·ñÔò»á±¨Undefined symbols for architecture i386:
_OBJC_CLASS_$µÄ´íÎ󣩣º

ÔÚSchemeÖÐÑ¡ÖÐGHUnitTestsÖеÄÄ£ÄâÆ÷£º

Command + R£¬¿ÉÒÔ¿´µ½Ò»¸ö²âÊÔ½çÃæ¡£µã»÷ÓÒÉϽǵÄRun£¬¾Í¿ÉÒÔÔËÐÐÁбíÖеÄËùÓе¥Ôª²âÊÔ£º

µã»÷±í¸ñÖеÄÒ»ÐУ¬¿ÉÒԲ鿴²âÊÔÐÅÏ¢£¨µ±È»¿ØÖÆÌ¨Ò²ÓÐÊä³ö£©£º

¶Ô±ÈÆðʹÓÃXCTest¿ò¼ÜÔÚ¿ØÖÆÌ¨µÄÊä³öºÃ¿´¶àÁË¡£
С½á
½¨ÒéʹÓÃGHUnit + OCMock×éºÏ½øÐе¥Ôª²âÊÔ£¬¹¦ÄÜÇ¿´ó½çÃæÃÀ¹Û¡£µ±È»Ò²ÓÐÈËÊÇÓÃXCTest
+ xctool + OCMockµÄ£¬xctoolÊÇFacebook³öÆ·£¬Ó¦¸ÃÒ²ÊǷdz£Ç¿´óµÄ¹¤¾ß£¬µ«ÊÇСµÜÔÚ»ú×ÓÉÏÓÃbrewÒ»Ö±×°²»ÉÏxctool£¨ÔÝʱ»¹Ã»ÕÒµ½½â¾ö·½·¨£©£¬ËùÒÔÕâÀï¾Í²»ËµxctoolµÄ²¿·ÖÁË¡£
iOS²âÊÔ-OCMockºÍGHUnit£¨Ò»£©
|