Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Unit Testing of Objective-C

The Unit Testing of Objective-C

Speaking at Cocoa Studies Kansai

cockscomb

June 02, 2013
Tweet

More Decks by cockscomb

Other Decks in Programming

Transcript

  1. • Built-in • Easy to setup • Just select “Include

    Unit Tests” when creating projects • Crazily easy executing • ⌘ + U™ OCUnit
  2. #import <SenTestingKit/SenTestingKit.h> @interface Tests : SenTestCase @end @implementation Tests -

    (void)setUp { [super setUp]; } - (void)tearDown { [super tearDown]; } - (void)testExample { STFail(@"Unit tests are not implemented yet in Tests"); } @end
  3. • Very simple • But… wait, • QUESTION: How to

    test asynchronous process, like delegate and blocks? •ANSWER: Do `while` •or use great third-party plug-ins
  4. #import <GHUnitIOS/GHUnit.h> @interface ExampleTest : GHTestCase { } @end @implementation

    ExampleTest - (void)setUpClass { } - (void)tearDownClass { } - (void)setUp { } - (void)tearDown { } - (void)testFoo { NSString *a = @"foo"; GHAssertNotNULL(a, nil); NSString *b = @"bar"; GHAssertEqualObjects(a, b, @"A custom error message. a should be equal to: %@.", b); } @end
  5. @interface ExampleAsyncTest : GHAsyncTestCase { } @end @implementation ExampleAsyncTest -

    (void)testURLConnection { [self prepare]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http:// www.google.com"]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testURLConnection)]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self notify:kGHUnitWaitStatusFailure forSelector:@selector(testURLConnection)]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { GHTestLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); } @end
  6. Kiwi • BDD for iOS • Simple to setup and

    use • Supporting CocoaPods • Supported by AppCode 2.0 • ⌘ + U™, OMG
  7. describe(@"Team", ^{ context(@"when newly created", ^{ it(@"should have a name",

    ^{ id team = [Team team]; [[team.name should] equal:@"Black Hawks"]; }); it(@"should have 11 players", ^{ id team = [Team team]; [[[team should] have:11] players]; }); }); });
  8. #import "Kiwi.h" SPEC_BEGIN(SpecName) describe(@"ClassName", ^{ context(@"a state the component is

    in", ^{ __block id variable = nil; beforeAll(^{}); afterAll(^{}); beforeEach(^{ variable = [MyClass instance]; }); afterEach(^{}); it(@"should do something", ^{ [[variable should] meetSomeExpectation]; }); specify(^{ [variable shouldNotBeNil] }); pending(@"something unimplemented", ^{}); }); }); SPEC_END
  9. id car = [Car car]; [car shouldNotBeNil]; [[car should] beKindOfClass:[Car

    class]]; [[car shouldNot] conformToProtocol:@protocol(FlyingMachine)]; [[[car should] have:4] wheels]; [[theValue(car.speed) should] equal:theValue(42.0f)]; [[[car should] receive] changeToGear:3];
  10. id carMock = [Car mock]; [[carMock should] beMemberOfClass:[Car class]]; [[carMock

    should] receive:@selector(currentGear) andReturn:theValue(3)]; [[theValue(carMock.currentGear) should] equal:theValue(3)]; id carNullMock = [Car nullMock]; [[theValue(carNullMock.currentGear) should] equal:theValue(0)]; [carNullMock applyBrakes]; id flyerMock = [KWMock mockForProtocol: @protocol(FlyingMachine)]; [[flyerMock should] conformToProtocol: @protocol(FlyingMachine)]; [flyerMock stub:@selector(dragCoefficient) andReturn:theValue(17.0f)]; id flyerNullMock = [KWMock nullMockForProtocol: @protocol(FlyingMachine)]; [flyerNullMock takeOff]; [subject stub:(SEL)aSelector];
  11. context(@"Fetching service data", ^{ it(@"should receive data within one second",

    ^{ [[LRResty client] get:@"http://www.example.com" withBlock: ^(LRRestyResponse* r) { NSLog(@"That's it! %@", [r asString]); fetchedData = [r asString]; }]; [[expectFutureValue(fetchedData) shouldEventually] beNonNil]; }); });
  12. • Most powerful • Including mocks and stubs • Characteristic

    style using blocks • Simple and easy • Highly recommended
  13. Nocilla • HTTP stubbing for iOS • Easy DSL interface

    • NSURLProtocol • Supporting AFNetworking
  14. • There’s so many solutions for TDD Cocoa • Make

    decision what’s frameworks to use • and I chosen Kiwi, Nocilla, UIAutomation • Test, Test, Test… Overall