How to add OCMock to XCode 7

2 Comments

Based on instructions from here http://ocmock.org/

Down here http://ocmock.org/download/ and extract to somewhere into your project like this.

Screen Shot 2015-09-25 at 8.47.50 AM

Then follow instructions here http://ocmock.org/ios/

Add the library
Screen Shot 2015-09-25 at 8.49.19 AM

Set the linker flags
Screen Shot 2015-09-25 at 8.51.08 AM

Make headers available
Screen Shot 2015-09-25 at 8.50.22 AM

Add code

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import "TaxCalculator.h"
#import "SubscriptionManager.h"

@interface TaxCalculatorTest : XCTestCase
@property (nonatomic, strong) TaxCalculator *calculator;
@end

@implementation TaxCalculatorTest

- (void)setUp {
    [super setUp];
    self.calculator = [TaxCalculator new];
}

- (void)testExample {
    XCTAssertEqual(0, [self.calculator calculateTax]);
    id mockSubscriptionManager = OCMClassMock([SubscriptionManager class]);
}

@end

How to add command line interface to xcode project

Leave a comment

This is how you can add command line interface to youx XCode command line app.

Add a new Objective-C file

add-new-objective-c-file

add-new-objc-file-with-name

Rename the Objective-C file extension to .mm

rename-dot-m

to-dot-m-m

Add a new header file

add-new-header-file

Copy in the following code to the header file

IOHelper.h

#import <Foundation/Foundation.h>


@interface IOHelper : NSObject

- (NSString *)readLine;

- (void)outputLine:(NSString *)line;

@end

copy-h

Copy in the following code to the .mm file

IOHelper.mm

#import "IOHelper.h"
#include <string>
#include <iostream>

@implementation IOHelper

- (NSString *)readLine
{
    std::string input;

    getline(std::cin, input);

    return [NSString stringWithCString:input.c_str()
                              encoding:[NSString defaultCStringEncoding]];
}

- (void)outputLine:(NSString *)line
{
    std::string outputLine([line cStringUsingEncoding:[NSString defaultCStringEncoding]]);

    std::cout << outputLine << std::endl;
}

@end

copy-mm

Copy in the following code to the main.m file

main.m

#import <Foundation/Foundation.h>
#import "IOHelper.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        IOHelper *io = [IOHelper new];
        
        [io outputLine:@"Hi! Welcome to XpStuff 2014-06-12."];
        [io outputLine:@"Who are you?"];
        
        NSString *name = [io readLine];
        
        [io outputLine:[NSString stringWithFormat:@"OK %@, go build a game!", name]];
    }
    return 0;
}

Run (Command + R). Should see the following in the console (Command + Shift + Y).

should-see-following

How to create a xcode command line project with tests xcode 6

3 Comments

Create new command line project

create-new-command-line-project

Add new test target by clicking ‘+’ sign in the white area under Targets (Foo)

add-new-target-1

And then selecting ‘Cocoa Testing Bundle’

add-test-target1

add-test-target-2

Edit your project scheme

edit-scheme-1

Select the ‘Test’ scheme

select-test-scheme

Hit the ‘+’ sign again, and select your test bundle.

select-test-bundle

select-test-bundle-2

Open logging window (Shift + Command + Y)
Command + U show now run all the tests.

tests-run

Voila!

Note: Whenever you add any new project files, you will need to include them in the test target (command line tool apps only).

target-member-ship

target-membership-2

How to access a private method in objective-c for testing

2 Comments

Say you’ve got a private method

-(NSUInteger)stackCount {
    return [self.myStack count];
}
@end

And you would like access to it in your test.

- (void)testAddNumberToStack {
    Calculator *calc = [Calculator new];
    [calc pushOperand:1.0];
    XCTAssertEqual(1, calc.stackCount);
}

You could expose it publicly in your header, but that would means exposing our privates (something we prefer to avoid). One neat thing I didn’t appreciate Objective-C could do was simply re-create the interface you want for your object under test in your test class, exposing the method you want to call, and then calling it from there.

@interface Calculator (Tests)
-(NSUInteger)stackCount;
@end

@implementation CalculatorTest

- (void)testAddNumberToStack {
    Calculator *calc = [Calculator new];
    [calc pushOperand:1.0];
    XCTAssertEqual(1, calc.stackCount);
}
@end

It may seem like cheating a bit. But because Objective-c is just a method based language of communication, we can define the message we want to send the object, and just send it assuming that when the tests runs, the method is going to be there.

Thanks to Mikael for showing me this trick. Means I can keep certain methods private, yet get access to them when I want for testing. Var kul!

Complete source

Calculator.h

#import &lt;Foundation/Foundation.h&gt;

@interface Calculator : NSObject
// operations
-(double)result;
-(void)pushOperand:(double)number;
@end

Calculator.m

#import &quot;Calculator.h&quot;

@interface Calculator()
@property (nonatomic, strong) NSMutableArray *myStack;
@end

@implementation Calculator

-(NSMutableArray *)myStack {
    if (!_myStack) _myStack = [NSMutableArray new];
    return _myStack;
}

-(double) result {
    return 0;
}

-(NSUInteger)stackCount {
    return [self.myStack count];
}

-(void)pushOperand:(double)number {
    NSNumber *operandNumber = [NSNumber numberWithDouble:number];
    [self.myStack addObject:operandNumber];
}

@end

Calculatortest.m

#import &lt;XCTest/XCTest.h&gt;
#import &quot;Calculator.h&quot;

@interface CalculatorTest : XCTestCase
@end

@interface Calculator (Tests)
-(NSUInteger)stackCount;
@end

@implementation CalculatorTest

- (void)setUp {
    [super setUp];
}

- (void)testCreateEmptyStack {
    Calculator *calc = [Calculator new];
    XCTAssertEqual(0, calc.result);
}

- (void)testAddNumberToStack {
    Calculator *calc = [Calculator new];
    [calc pushOperand:1.0];
    XCTAssertEqual(0, calc.result);
    XCTAssertEqual(1, calc.stackCount);
}

@end

How to extend a readonly property class objectivec

Leave a comment

Say you have a readonly property class testing).

@interface SPTAlbum
@property (nonatomic, readonly) NSArray *artists;

you want to make it’s properties readwrite (say for unit testing).

Here’s how you do it.

Create the new MockClass extending the readonly class.
Add a readwrite property that you want to overwrite.
Then synthesize it (because it is readonly in the base, it’s doesn’t know how to set so we help it by offering synthesizing it).

MockSPTAlbum.h

#import <Spotify/Spotify.h>

@interface MockSPTAlbum : SPTAlbum
@property (nonatomic, readwrite) NSArray *artists;
@end

MockSPTAlbum.m

#import "MockSPTAlbum.h"

@implementation MockSPTAlbum
@synthesize artists;
@end

Now you should be able to instantiate and set just like any other class. Happy testing!

http://stackoverflow.com/questions/14550266/how-to-turn-a-readonly-property-into-readwrite-property-in-objective-c

XCode Autolayout

Leave a comment

There’s been some changes in XCode since I last did iOS.

Do get a basic layout, just drag your elements out onto the page.

Basically, hold down the control key, left click and drag off your image to the space around it, and some pop-ups should appear that will let you auto center.

autolayout

Select center horizontally or vertically.

You can also control drag onto yourself.

autolayout-drag-onto-yourself

You can also select some stuff in the menu to help resolve autolayout issues.

autolayout-editor-options

Now here’s the tricky bit. See that wAnyhAny thing at the bottom? Make sure it looks like this. If you mess with this and you don’t know what you are doing (like me) you will have some elements not appear when you run the simulator – basically because this governs whether you are on iPad, iPhone, landscape ect. So if you get this wrong, your elements may not ever show up (depending on the simulator hardware you select).

wAnyHany

If you ever want to see all the elements you have on your view, click that little box in the lower right hand corner. You can then delete or do whatever you want with them.

element-view

iOS Boot Camp Coming to Montreal Nov 7-8

Leave a comment

November 7-8 me and my colleagues are going to Montreal for the first time offering our iOS Bootcamp at the Apple Regional office in St-Laurent.

This course is perfect for developers looking to get into iPhone development or just have an idea for an app they’d like build to turn into reality.

If you want to get into iOS development, and you would like a distilled, tight, 2 day course to get you there this is the course for you.

Signup now

See you there.

Jonathan

Older Entries Newer Entries

Follow

Get every new post delivered to your Inbox.

Join 339 other followers

%d bloggers like this: