Giter Club home page Giter Club logo

ocmock's Introduction

OCMock

Build Status

OCMock is an Objective-C implementation of mock objects.

For downloads, documentation, and support please visit ocmock.org.

ocmock's People

Contributors

benstiglitz avatar bgerstle avatar carllindberg avatar dmaclach avatar erikdoe avatar ian-twilightcoder avatar ikashkuta avatar imhuntingwabbits avatar kushalp avatar madsolar8582 avatar manuyavuz avatar marklarr avatar matrush avatar modocache avatar morganchen12 avatar nlutsenko avatar nrbrook avatar orta avatar packatino avatar parallaxe avatar paulb777 avatar pawel-sekara avatar philippec avatar pietbrauer avatar sdefresne avatar sgl0v avatar sigito avatar stevefortune avatar stig avatar we7teck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ocmock's Issues

NSGetSizeAndAlignment(): unsupported type encoding spec 'b' at 'b16b16*^{__CFString}}16' in '{_CAPropertyInfo=I[2:]b16b16*^{__CFString}}16'

This is when creating a mock for a plain old object

XCode 5.1.1, unit testing in simulator 64-bit

* thread #1: tid = 0x169149, 0x0000000103593973 libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x0000000103593973 libobjc.A.dylib`objc_exception_throw
    frame #1: 0x0000000103818cb4 CoreFoundation`__NSGetSizeAndAlignment + 2628
    frame #2: 0x0000000103818745 CoreFoundation`__NSGetSizeAndAlignment + 1237
    frame #3: 0x000000010382457f CoreFoundation`__NSMS1 + 63
    frame #4: 0x000000010382492e CoreFoundation`__NSMS1 + 1006
    frame #5: 0x0000000103823ead CoreFoundation`+[NSMethodSignature signatureWithObjCTypes:] + 749
    frame #6: 0x000000010f228bdb <REDACTED>Tests`+[NSObject(self=0x000000010d5b2ae0, _cmd=0x000000010d302400, aSelector=0x00000001021f482c) instanceMethodForwarderForSelector:] + 59 at NSObject+OCMAdditions.m:29
    frame #7: 0x000000010f229446 <REDACTED>Tests`-[OCClassMockObject setupForwarderForClassMethodSelector:](self=0x000000010d568800, _cmd=0x000000010d3023a0, selector=0x00000001021f482c) + 118 at OCClassMockObject.m:110
    frame #8: 0x000000010f229315 <REDACTED>Tests`__54-[OCClassMockObject prepareClassForClassMethodMocking]_block_invoke(.block_descriptor=<unavailable>, selector=0x00000001021f482c) + 101 at OCClassMockObject.m:99
    frame #9: 0x000000010f228cbf <REDACTED>Tests`+[NSObject(self=0x000000010373cc78, _cmd=0x000000010d3023d0, aClass=0x0000000100736c88, aBlock=0x00007fff5fbfc028) enumerateMethodsInClass:usingBlock:] + 143 at NSObject+OCMAdditions.m:48
    frame #10: 0x000000010f22927f <REDACTED>Tests`-[OCClassMockObject prepareClassForClassMethodMocking](self=0x000000010d568800, _cmd=0x000000010d302300) + 831 at OCClassMockObject.m:97
    frame #11: 0x000000010f228d64 <REDACTED>Tests`-[OCClassMockObject initWithClass:](self=0x000000010d568800, _cmd=0x000000010a7f9404, aClass=0x0000000100736c60) + 100 at OCClassMockObject.m:31
    frame #12: 0x000000010f22e46d <REDACTED>Tests`+[OCMockObject mockForClass:](self=0x000000010f3243a0, _cmd=0x0000000100527ac7, aClass=0x0000000100736c60) + 61 at OCMockObject.m:48
    frame #13: 0x000000010f043ec5 <REDACTED>Tests`__29-[MRAssetSpec spt_defineSpec]_block_invoke(.block_descriptor=0x000000010d5cf640) + 229 at MRAssetSpecs.m:22
    frame #14: 0x000000010f239d79 <REDACTED>Tests`runExampleBlock(block=0x000000010d5cf640, name=0x0000000114915410) + 1449 at SPTExampleGroup.m:70
    frame #15: 0x000000010f239611 <REDACTED>Tests`-[SPTExampleGroup runBeforeHooks:](self=0x000000010d5cf710, _cmd=0x000000010d303030, compiledName=0x000000010d5cf9f0) + 1969 at SPTExampleGroup.m:245
    frame #16: 0x000000010f23b200 <REDACTED>Tests`__48-[SPTExampleGroup compileExamplesWithNameStack:]_block_invoke(.block_descriptor=<unavailable>) + 144 at SPTExampleGroup.m:305
    frame #17: 0x000000010f24001d <REDACTED>Tests`-[SPTXCTestCase spt_runExampleAtIndex:](self=0x000000010e6ae610, _cmd=0x000000010d303580, index=0) + 509 at SPTXCTestCase.m:95
    frame #18: 0x0000000103829f1c CoreFoundation`__invoking___ + 140
    frame #19: 0x0000000103829dc4 CoreFoundation`-[NSInvocation invoke] + 308
    frame #20: 0x000000010d726c40 XCTest`-[XCTestCase invokeTest] + 161
    frame #21: 0x000000010d726d2c XCTest`-[XCTestCase performTest:] + 91
    frame #22: 0x000000010f2408f9 <REDACTED>Tests`-[SPTXCTestCase performTest:](self=0x000000010e6ae610, _cmd=0x000000010d72a71c, run=0x000000010d5befe0) + 137 at SPTXCTestCase.m:147
    frame #23: 0x000000010d727a75 XCTest`-[XCTest run] + 65
    frame #24: 0x000000010d7264df XCTest`-[XCTestSuite performTest:] + 125
    frame #25: 0x000000010d727a75 XCTest`-[XCTest run] + 65
    frame #26: 0x000000010d7264df XCTest`-[XCTestSuite performTest:] + 125
    frame #27: 0x000000010d727a75 XCTest`-[XCTest run] + 65
    frame #28: 0x000000010d7264df XCTest`-[XCTestSuite performTest:] + 125
    frame #29: 0x000000010d727a75 XCTest`-[XCTest run] + 65
    frame #30: 0x000000010d7291b4 XCTest`+[XCTestProbe runTests:] + 138
    frame #31: 0x00000001016e36dc Foundation`__NSFireDelayedPerform + 354
    frame #32: 0x00000001037f6c34 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    frame #33: 0x00000001037f67b2 CoreFoundation`__CFRunLoopDoTimer + 962
    frame #34: 0x00000001037df7be CoreFoundation`__CFRunLoopRun + 1614
    frame #35: 0x00000001037ded83 CoreFoundation`CFRunLoopRunSpecific + 467
    frame #36: 0x0000000104a0cf04 GraphicsServices`GSEventRunModal + 161
    frame #37: 0x000000010243ee33 UIKit`UIApplicationMain + 1010
    frame #38: 0x0000000100088675 <REDACTED>`main(argc=8, argv=0x00007fff5fbfec60) + 181 at main.m:16

"No mock for class (null)" when partially mocked class has been previously class mocked.

I've been trying to track down some problems in my tests relating to mock related exceptions in OCMGetAssociatedMockForClass. After some fiddling and disabling of tests I've narrowed replication down.

The following code will work perfectly so long as the TABAPIRequestOperation class has not been class mocked before:

apiRequestOperation = OCMClassMock(TABAPIRequestOperation.class);
request = OCMPartialMock(request);
OCMStub([request createAPIRequestOperation]).andReturn(apiRequestOperation);
OCMStub([request startAfterDelay:0 originalRepeatInterval:0]);

This is the case if a previous spec that mocks TABAPIRequestOperation has been disabled. I can replicate the exception "No mock for class (null)" by creating a Class mock for the Partially Mocked Object of the same Class immediately before:

OCMClassMock(TABAPIPollingRequestOperation.class);
apiRequestOperation = OCMClassMock(TABAPIRequestOperation.class);
request = OCMPartialMock(request);
OCMStub([request createAPIRequestOperation]).andReturn(apiRequestOperation);
OCMStub([request startAfterDelay:0 originalRepeatInterval:0]);

In order to track down the source of this, I've placed some logging code in OCMGetAssociatedMockForClass:

OCClassMockObject *OCMGetAssociatedMockForClass(Class aClass)
{
  if(![NSThread isMainThread]) {
    [NSException raise:NSInternalInconsistencyException format:@"NAUGHTY CONCURRENCY"];
  }

  NSLog(@"Obtaining Associated Mock for Class %@", NSStringFromClass(aClass));

  OCClassMockObject *mock = nil;
  while((mock == nil) && (aClass != nil))
  {
    mock = objc_getAssociatedObject(aClass, OCMClassMethodMockObjectKey);
    aClass = class_getSuperclass(aClass);
    NSLog(@"Mock %@ for class %@", mock, NSStringFromClass(aClass));
  }
  if(mock == nil)
      [NSException raise:NSInternalInconsistencyException format:@"No mock for class %@", NSStringFromClass(aClass)];
  return mock;
}

This confirms that there is no non-main thread access to elimiate concurrent access as the source of the problem as well as prints the inheritance chain right before the before the crash:

2014-05-30 08:25:01.238 SunTablet[53580:60b] Obtaining Associated Mock for Class TABAPIPollingRequestOperation
2014-05-30 08:25:01.238 SunTablet[53580:60b] Mock (null) for class NSOperation
2014-05-30 08:25:01.238 SunTablet[53580:60b] Mock (null) for class NSObject
2014-05-30 08:25:01.239 SunTablet[53580:60b] Mock (null) for class (null)

And here is the backtrace:

(lldb) bt
* thread #1: tid = 0x8c0ea, 0x0d03e672 SunTabletTests`OCMGetAssociatedMockForClass(aClass=0x00000000) + 226 at OCMFunctions.m:139, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0d03e672 SunTabletTests`OCMGetAssociatedMockForClass(aClass=0x00000000) + 226 at OCMFunctions.m:139
    frame #1: 0x0d03cb7d SunTabletTests`-[OCClassMockObject forwardInvocationForClassObject:](self=0x0d07bc6c, _cmd=0x019e471b, anInvocation=0x0ba6ec90) + 45 at OCClassMockObject.m:112
    frame #2: 0x01fe52da CoreFoundation`___forwarding___ + 458
    frame #3: 0x01fe50ee CoreFoundation`__forwarding_prep_0___ + 14
    frame #4: 0x0d03c5f4 SunTabletTests`-[OCClassMockObject prepareClassForClassMethodMocking](self=0x116e7a50, _cmd=0x0bc52820) + 132 at OCClassMockObject.m:71
    frame #5: 0x0d03c391 SunTabletTests`-[OCClassMockObject initWithClass:](self=0x116e7a50, _cmd=0x0456c7bc, aClass=0x0d07bc6c) + 113 at OCClassMockObject.m:31
    frame #6: 0x0d040e76 SunTabletTests`+[OCMockObject mockForClass:](self=0x0d07c374, _cmd=0x0bc52ab0, aClass=0x0d07bc6c) + 86 at OCMockObject.m:46
    frame #7: 0x0d040fe5 SunTabletTests`+[OCMockObject niceMockForClass:](self=0x0d07c374, _cmd=0x0bc52060, aClass=0x0d07bc6c) + 69 at OCMockObject.m:62
    frame #8: 0x0d00d20a SunTabletTests`__51-[TABAPIPollingRequestOperationSpec spt_defineSpec]_block_invoke2(.block_descriptor=0x116de030) + 394 at TABAPIPollingRequestSpec.m:40
    frame #9: 0x0d04e6fc SunTabletTests`runExampleBlock(block=0x116de030, name=0x116edc80) + 1500 at SPTExampleGroup.m:70
    frame #10: 0x0d04df23 SunTabletTests`-[SPTExampleGroup runBeforeHooks:](self=0x116de170, _cmd=0x0bc535a0, compiledName=0x116de520) + 2083 at SPTExampleGroup.m:245
    frame #11: 0x0d04fcd8 SunTabletTests`__48-[SPTExampleGroup compileExamplesWithNameStack:]_block_invoke(.block_descriptor=<unavailable>) + 152 at SPTExampleGroup.m:305
    frame #12: 0x0d054e8c SunTabletTests`-[SPTXCTestCase spt_runExampleAtIndex:](self=0x116e1ea0, _cmd=0x0bc53b00, index=1) + 556 at SPTXCTestCase.m:95
    frame #13: 0x01fe991d CoreFoundation`__invoking___ + 29
    frame #14: 0x01fe982a CoreFoundation`-[NSInvocation invoke] + 362
    frame #15: 0x20103c6c XCTest`-[XCTestCase invokeTest] + 221
    frame #16: 0x20103d7b XCTest`-[XCTestCase performTest:] + 111
    frame #17: 0x0d055878 SunTabletTests`-[SPTXCTestCase performTest:](self=0x116e1ea0, _cmd=0x20107ed4, run=0x0ba6b900) + 152 at SPTXCTestCase.m:147
    frame #18: 0x20104c48 XCTest`-[XCTest run] + 82
    frame #19: 0x201033e8 XCTest`-[XCTestSuite performTest:] + 139
    frame #20: 0x20104c48 XCTest`-[XCTest run] + 82
    frame #21: 0x201033e8 XCTest`-[XCTestSuite performTest:] + 139
    frame #22: 0x20104c48 XCTest`-[XCTest run] + 82
    frame #23: 0x201033e8 XCTest`-[XCTestSuite performTest:] + 139
    frame #24: 0x20104c48 XCTest`-[XCTest run] + 82
    frame #25: 0x201066ba XCTest`+[XCTestProbe runTests:] + 183
    frame #26: 0x004e05ec Foundation`__NSFireDelayedPerform + 372
    frame #27: 0x01fb3ac6 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
    frame #28: 0x01fb34ad CoreFoundation`__CFRunLoopDoTimer + 1181
    frame #29: 0x01f9b538 CoreFoundation`__CFRunLoopRun + 1816
    frame #30: 0x01f9a9d3 CoreFoundation`CFRunLoopRunSpecific + 467
    frame #31: 0x01f9a7eb CoreFoundation`CFRunLoopRunInMode + 123
    frame #32: 0x03d2d5ee GraphicsServices`GSEventRunModal + 192
    frame #33: 0x03d2d42b GraphicsServices`GSEventRun + 104
    frame #34: 0x00ab4f9b UIKit`UIApplicationMain + 1225
    frame #35: 0x000040ad SunTablet`main(argc=8, argv=0xbfffed5c) + 141 at main.m:14

Interestingly this will only occur when the second code snippet has occured twice or more. If only one test case depends on this snippet occuring, there will be no exception thron This leads me to believe that there is some cleanup that is not occuring, though I am not that wise to the internals of OCMock. The documents say and I have verified that stopMocking: is called on the partial on dealloc, I've also added stopMocking to an afterEach to ensure teardown after each test.

Partial Mocks have their sharp edges, but in this case they are the 'least worst' incremental step to build out tests with a view to move towards less coupled and therefore more testable classes in the future.

stopMocking causes test crash with - CLTilesManagerClient: initialize, sSharedTilesManagerClient

This happens off and on. I can get it sometimes and others not. I'm not even using CoreLocation so have no idea why this is happening but it is flaky and we did not have it w/ OCMock 2.

The expect is actually passing but this keeps happening. When I remove the stopMocking in the afterEach, everything works exactly as expected. Any thoughts?

Log:

2014-07-17 18:14:12.604 App[4084:60b] CLTilesManagerClient: initialize, sSharedTilesManagerClient
2014-07-17 18:14:12.605 App[4084:60b] CLTilesManagerClient: init
2014-07-17 18:14:12.605 App[4084:60b] CLTilesManagerClient: reconnecting, 0xa9e9360

Threads:
screen shot 2014-07-17 at 6 15 10 pm

Line it pauses on:
screen shot 2014-07-17 at 6 26 58 pm

Here is the test:

it(@"should encrypt data", ^{
    NSString *key = @"key";
    NSData *unencrypedData = [@"encryptme" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encryptedData = [unencrypedData AES256EncryptedDataUsingKey:key error:nil];

    OCMStub([staticSubjectMock encryptionKey]).andReturn(key);

    NSData *newData = [WFCache encryptData:unencrypedData];

    expect(newData).to.equal(encryptedData);
});

Here is the code:

+ (NSData*)encryptData:(NSData*)dataToEncrypt {
    NSError *encryptionError;
    NSData *encryptedData = [dataToEncrypt AES256EncryptedDataUsingKey:[WFCache encryptionKey]
                                                                 error:&encryptionError];
    if (encryptionError) {
        NSLog(@"%@ - ERROR encrpyting data", TAG);
        return nil;
    } else {
        return encryptedData;
    }
}

The only other thing we do is a beforeEach:

    beforeEach(^{
        subject = [[WFCache alloc] init];
        subjectMock = OCMPartialMock(subject);
    });

Protocol mocking should support class methods

This issue was raised here: http://stackoverflow.com/q/26592513/449161

The implementation of protocol mock doesn't allow for the mocking of protocol class methods. It's appears to be a straightforward fix:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    struct objc_method_description methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, YES, YES);
    if(methodDescription.name == NULL) 
    {
        methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, NO, YES);
    }
    // For required class methods:
    if (methodDescription.name == NULL)
    {
        methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, YES, NO);
    }
    // For optional class methods
    if (methodDescription.name == NULL)
    {
        methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, NO, NO);
    }
    if(methodDescription.name == NULL)
    {
        return nil;
    }

I built this locally and didn't see it break any tests. It worked in my test though I didn't write formal tests for it.

OCMock 3: Stub ignores andReturn, returns nil if typedef parameter expects [OCMArg any]

In OCMock 3.0.2, a stub for a method that takes a parameter will:

  1. successfully honor the andReturn value if the parameter is a normal class type.
  2. ignore the andReturn value and always return nil if the parameter is a typedef, and if the argument specified in the stub invocation is [OCMArg any]
  3. successfully honor the andReturn value if the parameter is a typedef, and if the argument specified in the stub invocation is the actual expected argument value.

In this test case, the first and third tests pass, while the second fails:

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>

typedef NSString TypedefString;

@interface StubWithTypedefFailureDemo : NSObject
- (NSString *)stringForTypedef:(TypedefString *)string;
- (NSString *)stringForString:(NSString *)string;
@end

@implementation StubWithTypedefFailureDemo
- (NSString *)stringForString:(NSString *)string
{
    NSAssert(NO, @"This never happens.  Body replaced by stub.");
    return @"Whatever.  Doesn't matter.";
}
- (NSString *)stringForTypedef:(TypedefString *)string
{
    NSAssert(NO, @"This never happens.  Body replaced by stub.");
    return @"Whatever.  Doesn't matter.";
}
@end


@interface StubWithTypedefFailureDemoTests : XCTestCase
@property (strong, nonatomic) id demo;
@property (strong, nonatomic) id actualParameter;
@property (strong, nonatomic) id expectedReturn;
@end

@implementation StubWithTypedefFailureDemoTests

- (void)setUp
{
    [super setUp];
    self.demo = OCMClassMock([StubWithTypedefFailureDemo class]);
    self.actualParameter = @"actualParameter";
    self.expectedReturn = @"expectedReturn";
}

- (void)testStringForStringStubWithOCMArgAnyParameter_PASSES
{
    [[[self.demo stub] andReturn:self.expectedReturn] stringForString:[OCMArg any]];
    id actualReturn = [self.demo stringForString:self.actualParameter];
    XCTAssertEqualObjects(actualReturn, self.expectedReturn, @"actualReturn %@ differs from expectedReturn %@", actualReturn, self.expectedReturn);
}

- (void)testStringForTypedefStubWithOCMArgAnyParameter_FAILS
{
    [[[self.demo stub] andReturn:self.expectedReturn] stringForTypedef:[OCMArg any]];
    id actualReturn = [self.demo stringForTypedef:self.actualParameter];
    // This fails!  actualReturn is nil here.
    XCTAssertEqualObjects(actualReturn, self.expectedReturn, @"actualReturn %@ differs from expectedReturn %@", actualReturn, self.expectedReturn);
}

- (void)testStringForTypedefStubWithActualParameter_PASSES
{
    [[[self.demo stub] andReturn:self.expectedReturn] stringForTypedef:self.actualParameter];
    id actualReturn = [self.demo stringForTypedef:self.actualParameter];
    XCTAssertEqualObjects(actualReturn, self.expectedReturn, @"actualReturn %@ differs from expectedReturn %@", actualReturn, self.expectedReturn);
}

@end

Class method stubs on partial mocks aren't removed correctly

If in one test method...

id mockObject = [OCMockObject partialMockForObject:realObject];
[[[mockObject stub] andReturn:mockObject] getObjectInstance];
[mockObject stopMocking]

...and then in a test in another class somewhere else that's run later...

id realObject = [ObjectClass getObjectInstance];

The supposedly unmocked call to the class method never happens. It cannot be stepped into, and a breakpoint inside it is not hit. nil is returned.

The workaround is to use another mock object, separate to the partial mock, to add the class method stub.

Mock class methods from library doesn't work

Setup:
We stub a class method in a XCTest method:

- (void) testStub {
  id mock = [OCMock mockForClass:[SomeTestClass class]];
  [[[mock stub] andReturn:@"Test"] someClassMethod];

 SomeViewController *viewController = [[SomeViewController] alloc] init];
 [viewController viewDidLoad];
 XCTAssertEqualObjects(view.someString, @"Test");
}

and in viewDidLoad the class method someClassMethod is called and set to someString

This works fine.

But if we move SomeTestClass to an CocoaPod Library and integrate it to the project with CocoaPods the class method stubing doesn't work.

We made a little example project for this issue https://github.com/x2on/OCMock-Test-Project

Any idea why this happens?

Can't stub class-method 'class'

My project includes an optional framework, so I need to check for its availability.
This is how I do it:

- (BOOL)availabilityCheck {
    return (SomeClass.class != nil);
}

So for Unit Testing I want to stub the class method, and return nil.

OCMockObject *mock = [OCMockObject mockForClass:SomeClass.class];
[[[[mock stub] classMethod] andReturn:nil] class];

expect(someOtherObject.availabilityCheck).to.equal(NO);

The test fails, and a NSStringFromClass still returns the correct class name.
For some reason, the class method can't be stubbed.

Why is that?

OCMock 3: Text field mocking fails in strange ways

I encountered an unexpected problem where simply creating a partial mock of an instance of UITextField contained within an other object results in this error if ‑resignFirstResponder is sent to the UITextField object:

-[OCMockTextFieldTest testCreateMock] failed: -[UITextInputTraits resignFirstResponder]: unrecognized selector sent to instance 0x102b05ba0

That was produced by running the test class I created to show the issue. I don't know the significance of this, but if the test method is written as follows, no error occurs:

- (void)testCreateMock
{
    UITextField *const textField = [UITextField new];
    id mockObject = OCMPartialMock(textField);
    [textField resignFirstResponder];
}

When stubbing partially mocked object, original object seem to be affected, too

Here is a simple test case. Class I want to test has following interface / implementation:

@interface Calculator : NSObject
- (NSNumber *)methodA;
- (NSNumber *)methodB;
@end

@implementation Calculator
- (NSNumber *)methodA {
    return [self methodB];
}
- (NSNumber *)methodB {
    return @0;
}
@end

And here is a test method for the partial mock:

- (void)testCalculator {
    Calculator *originalObject = [[Calculator alloc] init];
    Calculator *partialMock = OCMPartialMock(originalObject);
    [OCMStub([partialMock methodB]) andReturn:@42];
    XCTAssertEqualObjects([partialMock methodA], @42, @"Expecting 42");
    XCTAssertEqualObjects([originalObject methodA], @0, @"Expecting 0");
}

The test fails on the last assertion with message

(([originalObject methodA]) equal to (@0)) failed: ("42") is not equal to ("0") - Expecting 0

It seems like a simple enough test, maybe I'm doing something wrong?

OCMock 3.1: Class stub seems to be never called

Hi guys,
I'm trying to create a stub for a class method as explained in the documentation.

id mock = OCMClassMock([MyClass class]);
[[[mock stub] andReturn:mock] myFactoryWithParameter:[OCMArg any]];

When I try to call the factory in test code(into the method that specifies the test) everything works fine and I get the mock object as expected, but when I call the same factory method inside another method that is called by the test code, I get the "normal" object. It seems the stub is not executed.

[I get the mock]

- (void)test_somethingToTest
{
    id mock = OCMClassMock([MyClass class]);
    [[[mock stub] andReturn:mock] myFactoryWithParameter:[OCMArg any]];

    // "object" contains the mock
    MyClass *object = [MyClass myFactoryWithParameter:@"string"];
}

[I get the object as usual]

- (void)test_somethingToTest
{
    id mock = OCMClassMock([MyClass class]);
    [[[mock stub] andReturn:mock] myFactoryWithParameter:[OCMArg any]];

    [objectUnderTest someMethod];
}
...
- (void)someMethod
{
    // "object" contains the original object
    MyClass *object = [MyClass myFactoryWithParameter:@"string"];
}

I don't know if it is a bug or not, probably I'm doing something wrong. Any idea?

Thanks.

OCMock 2.2.3 issue when expect a method with a block as a parameter

I am using OCMOCK 2.2.3 and when I did this:

[[mock expect] GET:[OCMArg any] success:[OCMArg any] failure:[OCMArg any]];

I got this: -[OCMAnyConstraint copyWithZone:]: unrecognized selector sent to instance 0x8ab8990

It only happens when a parameter is a block, in this case success and failure parameters are blocks.

I think it doesn't happen in previous versions.

malloc error on recursive/chained calls to stubbed method

I'm trying to stub an async method in a partial mock:

id mock = OCMPartialMock([[MyClass alloc] init]);

void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation) {
    MyObjectWithAction *owa = nil;
    [invocation getArgument:&owa atIndex:3];
    if (owa && owa.action) {
        owa.action();
    }
};
OCMStub([mock myMethodWithParam:[OCMArg any]]).andDo(theBlock);

But inside "action()", I'm calling to "myMethodWithParam:" one more time (but this time with a "MyObjectWithAction" without action).

...and I'm getting:

malloc: *** error for object 0xdd59a20: pointer being freed was not allocated

EXC_BAD_ACCESS when partially mocking tagged pointers

Tagged pointers are utilized for NSDate, NSNumber, NSIndexPath, and other objects containing small amounts of data on 64-bit iOS devices.

A tagged pointer is a memory optimization. They are fake pointers that have the real data of the object shoved into them, if it's small enough to fit in the bytes of the pointer.

Unfortunately, this also seems to mean that a lot of objective-c runtime methods don't work, including objc_setAssociatedObject, which throws an EXC_BAD_ACCESS. If you check out this branch and run the OCMockLib tests on an iPhone Retina (4-inch 64-bit), you'll see what I'm talking about.

I'm not really sure how to solve this. The implementation of a tagged pointer seems to be, in a lot of ways, at the discretion of the class itself, so it's hard to say how these objects (such as __NSTaggedDate) are being encoded into the pointer. It'd be nice if we could turn them back into normal objects and pointers to those objects, but it seems difficult.

I don't see any information online about disabling the use of tagged pointers on 64-bit, but that would also be an solution if it were possible.

Creating a nice mock of class [UIView class] throws exception

*The exception occurs in this method:
(... NSObject+OCMAdditions.m ...)

+ (IMP)instanceMethodForwarderForSelector:(SEL)aSelector
{
    // use NSSelectorFromString and not @selector to avoid warning
    SEL selectorWithNoImplementation = NSSelectorFromString(@"methodWhichMustNotExist::::");

#ifndef __arm64__
    NSMethodSignature *sig = [self instanceMethodSignatureForSelector:aSelector];
    if([sig usesSpecialStructureReturn])
        return class_getMethodImplementation_stret(self, selectorWithNoImplementation);
#endif
    return class_getMethodImplementation(self, selectorWithNoImplementation);
}

at the following point of the method:

NSMethodSignature *sig = [self instanceMethodSignatureForSelector:aSelector];

*It is triggered by calling this method:

id mockView = OCMClassMock([UIView class]);

Stubs are removed when mocked alloc is called.

I would like to mock alloc then set up a stub on the mocked instance. However, the stub is being removed when alloc is called.

Best illustrated by an example:

id stringClassMock = [OCMockObject niceMockForClass:[NSString class]];

[[[stringClassMock stub] andReturn:stringClassMock] alloc];

[[[stringClassMock stub] andDo:^(NSInvocation * i) {

NSLog(@"This is not not called :( ");

}] enumerateLinesUsingBlock:OCMOCK_ANY];

// This line causes above stub to be removed,
// If you comment out this line it works.
NSString * myNewString = [[NSString alloc] init];

[stringClassMock enumerateLinesUsingBlock:nil];

Using OCMock (2.2.4)

Stub a key-value lookup in an implementation-agnostic way

Imagine trying to sort some objects:

id object1 = [OCMockObject mockForProtocol:@protocol(MyModel)];
id object2 = [OCMockObject mockForProtocol:@protocol(MyModel)];
[[[object1 stub] andReturn:@"B"] name];
[[[object2 stub] andReturn:@"A"] name];
//...
XCTAssertEqualObjects(sortedArray, @[object2, object1]);

I don't want to depend on how the sort is implemented, just on whether it works. If I use sortedArrayUsingDescriptors: then the test will fail because the implementation calls valueForKey: rather than calling the accessor directly. What I'd like to do is something like this:

[[[object1 stub] value:@"B"] forKey:@"name"];
[[[object2 stub] value:@"A"] forKey:@"name"];

which is both a convenience for stubbing -name, and stubs -valueForKey:.

KVC via keyPath is not working with OCMock

I have a object Controller that has a property that returns a mock object. I then ask Controller for valueForKeyPath: where the path is a path to the mock object's property. I can see in the debugger that valueForKeyPath: is correctly executed on the Controller and that it calls valueForKey: on the Controller object which returns the mocked object. However, the mocked object never gets a call to valueForKeyPath: or valueForKey:.

This is my mock creation:

self.reservationMock = [OCMockObject niceMockForClass:[Reservation class]];
self.sut = [[Controller alloc] initWithReservation:self.reservationMock];

The mock is stored in reservation. I evaluate a predicate with reservation.reservationMode on the sut.

I get the following calls:

  • valueForKeyPath:@"reservation.reservationMode"
  • valueForKey:@"reservation"

And that's it. If I do not mock the object, the evaluation continues with the following calls on the Reservation object.

  • valueForKeyPath:@"reservationMode"
  • valueForKey:@"reservationMode"

How to verify that a property has been accessed?

It's my first use of your library and I might be missing something but I wanted to expect that a property has been accessed.
As the accessor is a method I thought that would work but not at all :(

Here is the code:

YSUser *user = [[YSUser alloc] init];
id mockUser = [OCMockObject partialMockForObject:user];
[[[mockUser stub] andReturn:nil] username];
[[mockUser expect] username];
expect([validator validate:mockUser error:nil]).to.equal(NO);
[mockUser verify];

Here is the error: OCPartialMockObject[YSUser]: expected method was not invoked: username.

And my validate looks like that:

- (BOOL)validate:(YSUser *)user error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(user != nil);

    if ([user.username length] == 0) {
        if (error) {
            NSDictionary *userInfo = @{
                YSUserValidatorPropertyKey: NSStringFromSelector(@selector(username)),
                NSLocalizedDescriptionKey: @"mandatory property is empty"
            };
            *error = [NSError errorWithDomain:YSUserValidatorErrorDomain code:YSUserValidatorErrorMissingMandatoryProperty userInfo:userInfo];
        }

        return NO;
    }

    return YES;
}

Just in case I'm using specta and expecta.

Thanks

return nil on partial mocks doesn't work with OCMock 3

With OCMock i can't return nil on partial mocks:

id mock = OCMPartialMock([SomeManager sharedInstance]);
OCMStub([mock objectForKeyPath:@"some.keyPath"]).andReturn(nil);

i get the following error:

Return value does not match method signature; signature declares '@' but value is '^v'.

With OCMock 2 it works fine.

Any thoughts?

Using andCall: and returning an autoreleased object kills it too soon

When using andCall: on a stub, and returning an autoreleased object from within the method that is called, that object will end up being destroyed too soon.
This is apparently caused by the fact that the invocation is done from within an -[NSArray indexOfObjectPassingTest:] in -[OCMockObject handleInvocation:]. It looks like the block is wrapped in an autorelease pool, and so the object will be released as soon as the invocation is done, and before even returning to the actual caller...

Using reject with OCMock 3

In migrating to OCMock 3, I am running into problems with ‑reject on OCMockObject. The places I used it with OCMock 2 now report false negatives with v3. I have a simple reproduction that shows the issue.

Is there a new recommended practice for disallowing method invocations with OCMock 3?

OCMVerify causing EXC_BAD_ACESS

I've been using OCMock 2 for many months along side Specta without issue. Recently I upgraded to 3 and began using the OCMVerify macro for verify-after-running. In certain instances I am receiving EXC_BAD_ACCESS when the invocation matcher is matching arguments, specifically if(([recordedArg isEqual:passedArg] == NO). It seems the the passedArg is released by ARC at some point and by the time it is pulled out of the invocation it is gone.

I'm not 100% where the issue lies and I can't seem to be able to replicate this is a sample project to provide as an example for this issue. It seems to happen more on iOS 64bit simulator than 32bit, but it isn't everytime.

The layout of my tests look something like this:

SpecBegin(Spec)

describe(@"Spec", ^{

    __block TestSubject *subject;
    __block id mockObject;

    beforeAll(^{
        mockObject = OCMClassMock([MyObject class]);
        subject = [[TestSubject alloc] initWithObject:mockObject];
    });

    describe(@"when something happens", ^{

        beforeAll(^{
            MyInvocation successfulInvocation = [ArrangeInvocation successfulInvocation];

            OCMStub([mockObject anotherMethod]);
            .andDo(successfulInvocation);

            [subject doSomething];
        });

        it(@"does something", ^{
            OCMVerify([mockObject methodCalledWithParam:[SomeParam param] 
                                      completionHandler:OCMOCK_ANY]);
        });

    });

});

SpecEnd

I have been able to work around this issue by moving the expectation to before the tests run but ideally would like to use the new features of OCMock 3. I'm just not sure where to start diagnosing this and as I said can't seem to replicate the issue outside of my main codebase.

Partial mock for [UIApplication sharedApplication] results in crash

Previously I used OCMock to test the openURL: method on [UIApplication sharedApplication] for my login tests.

Since updating to OCMock 3, It errors every time:

[AppDelegate ocmock_replaced__controlTouchBegan:withEvent:]: unrecognized selector sent to instance 0xc02af20]

this is triggered from inside OCPartialMockObject.m, in the method:

- (id)forwardInvocationForRealObject:(NSInvocation *)anInvocation

Seems possible that the partial mock isn't properly swizzling?

Clarify License

http://ocmock.org/download/ has a MIT-like license, which is, however, fully proprietary stating "All rights reserved". Can you clarify if you intended to go with an approved open source license or whether you intend to provide commercial licenses when somebody wants to develop a product using this library?

NSFileManager mock not stopping

file:///%3Cunknown%3E: test failure: -[WFViewControllerSpec UIViewController_WFViewController_h_openModalView_should_open_a_view_from_the_storyboard] failed: There doesn't seem to be a valid compiled storyboard at path '/Users/johnbland/Library/Application Support/iPhone Simulator/7.1/Applications/9C594DFC-A063-421B-9169-DBE5F4324D6C/App.app/App.storyboardc'

This happens a ton. Comment out all NSFileManager mocks and it works as expected. Call stopMocking on the mock and it works. From the discussion on #118 I took away we should never need to do this.

Mock:

fileManagerMock = OCMClassMock([NSFileManager class]);
OCMStub([fileManagerMock defaultManager]).andReturn(fileManagerMock);

Then:

        afterEach(^{
            OCMVerifyAll(fileManagerMock);
            [fileManagerMock stopMocking];
        });

That's the only solution. Thoughts?

Forwarding all invocations to real object by default in "nice" partial mock

I'm having a very similar problem to #68 - I'm using partial mocks of NSManagedObjects to test my core data models.

At some places, I'm using real NSManagedObjects and that works great, at others I need to mock certain methods that produce computed values out of the model data, because they depend on a deep hierarchy of related NSManagedObjects.

When I mock these methods however, properties of these objects cannot be used anymore because there seems to be no way at the moment to mock them or set them.

What do you think about optionally having "nice" partial mocks, which behave just like the real objects except for the methods that have been mocked via andReturnValue:?

Infinite recursive loop on Class mock

The following is causing an infinite recursive loop when I execute my test in Xcode:

// This is inside a larger test method
self.mockSharing = [OCMockObject mockForClass:[Sharing class]];

[[[self.mockSharing expect] classMethod] shareMessage:message trackingString:[OCMArg isNil]];

[Sharing shareMessage:message];
////////

// This is the method that eventually expects shareMessage:trackingString: to occur
+ (void)shareMessage:(Message *)message
{
    if (!message)
    {
        return;
    }

    __block NSString *body = message.body;

    void (^complete)(void) = ^ {      
        [Sharing shareMessage:body trackingString:nil];
    };

    [Shortener shortenURLString:message.publicUrl withResponseBlock:^(NSURL *shortUrl, NSError *error) {

            if (shortUrl && !error)
            {
                body = [body stringByAppendingString:[NSString stringWithFormat:@" %@", shortUrl.absoluteString]];
            }

            complete();
    }];
}

screen shot 2014-06-25 at 12 27 37 pm

andReturnValue is broken in Xcode 5.1 when running tests in 64 bits mode

@interface Hoge : NSObject
@property (nonatomic) NSInteger fuga;
@end

id hogeMock = [OCMockObject mockForClass:[Hoge class]];
[[[hogeMock stub] andReturnValue:@(100)] fuga];

The log is below.

failed: Return value does not match method signature; signature declares 'q' but value is 'i'.

Could you tell me the solution?

Including OCMock 3.x via cocoapod in XCode 6 (beta 6) breaks compilation

I have not tried including OCMock into my project manually, any expectation that would have a different effect?

If I include OCMock 3.x with my podfile, I cannot compile my project. OCMock 2.x does work this way.

ld: framework not found XCTest
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Mocking accessor returning C++ objects pointer fails when using libc++

When testing Chrome on iOS, we found that mocked properties returning a C++ object (in our case a GURL) by pointer failed when building using libc++ and clang. It appears that the type descriptions returned by @encode(typeof(expr)) (from OCMOCK_VALUE) and -[[NSInvocation methodSignature] methodReturnType] have their properties recursively expanded, but with different depth, causing the strcmp to fail.

The code looks like:
@interface SomeClass
@Property (nonatomic, assign) const GURL* origin;
@EnD

const GURL kFakeOrigin = ....;
const GURL* fake_origin_ptr = &kFakeOrigin;
[[[mock_class stub] andReturnValue:OCMOCK_VALUE(fake_origin_ptr)] origin];

And the type descriptions in OCMBoxedReturnValueProvider.m are:
(lldb) p returnType
(const char _) $0 = 0x149e901d "r^{GURL={basic_string<char, std::__1::char_traits, std::__1::allocator >={__compressed_pair<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >::__rep, std::__1::allocator >={__rep}}}B{Parsed={Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}^{Parsed}}{scoped_ptr<GURL, base::DefaultDeleter >={scoped_ptr_impl<GURL, base::DefaultDeleter >={Data=^{GURL}}}}}"
(lldb) p valueType
(const char *) $1 = 0x149e5808 "r^{GURL={basic_string<char, std::__1::char_traits, std::__1::allocator >={__compressed_pair<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >::__rep, std::__1::allocator >={__rep=(?={_long=II}{__short=(?=Cc)[11c]}{__raw=[3L]})}}}B{Parsed={Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}^{Parsed}}{scoped_ptr<GURL, base::DefaultDeleter >={scoped_ptr_impl<GURL, base::DefaultDeleter >={Data=^{GURL}}}}}"

OCMRecorder BAD_ACCESS in dealloc

I'm getting a BAD_ACCESS in the dealloc of OCMRecorder for a test involving asynchronous methods. It seems invocationMatcher is being over released. If I remove the [invocationMatcher release] it's fine. This is with Xcode 6, iOS 8.

Cannot stub the same object more than once

I am trying to stub the same mock object more than once. I debugged the case and find out that Partial Mock objects are failing to stub properties after stubbing once.

- (void)testSomething{
    id partialMock = [OCMockObject partialMockForObject:self.someObject];
    [[[partialMock stub] andReturnValue:OCMOCK_VALUE(value)] someProperty];
    XCTAssertTrue(self.someObject.someProperty == value); // This test is passing

    [[[partialMock stub] andReturnValue:OCMOCK_VALUE(someOtherValue)] someProperty];
    XCTAssertTrue(self.someObject.someProperty == someOtherValue); // This test is failing
}

Using OCMock 3.x with test frameworks other than XCTest causes runtime crash

Hi there!

I'm using OCMock with a test framework called Cedar(https://github.com/pivotal/cedar). It is running tests in a separate target, that is not explicitly marked as "test" target by XCode. There's no injection in main target, it is just a separate target with a separate application delegate("CedarApplicationDelegate"). After launching app crashes on runtime with EXC_BREAKPOINT.

Console log:
dyld: Library not loaded: @rpath/XCTest.framework/XCTest

Reverting OCMock to 2.2 fixes the issue, since it is not dependent on XCTest.framework.

P.S. Using XCode 6.

Test suite is slowwwwwwww on OCMock 3

Are there any reasons why the tests run so much slower on 3 than on 2? Is there something we can do to speed things up?

It is painfully slow how. If I had to guess, 2-3x slower.

OCMockObject cannot stub or expect method

I'm getting an error when trying to expect a call on my mock, created from a protocol.

I'm trying to check that

  • the first argument "viewModel" is my own object.
  • the second property passed is valid with a formula (in this case I'm just using OCMArg.any, but it also happens with a block.
@protocol MyProtocol
- (void)viewModel:viewModel didReceiveSearchError:(NSError *)error;
@end

- (void)testOCMock
{
    id mock = [OCMockObject mockForProtocol:@protocol(MyProtocol)];
    [[mock expect] viewModel:self.viewModel didReceiveSearchError:[OCMArg any]];
}

I get this error:

OCMockObject[MyProtocol]: cannot stub or expect method 'viewModel:didReceiveSearchError:' because no such method exists in the mocked class.

If I remove the first parameter viewModel out of the function, everything works properly.

Thanks guys, great project!

Reference Update: 7.6 Limitations Section

id mock = OCMStrictClassMock([SomeClass class]);
OCMStub([mock someMethod]).andReturn(@"a string");
OCMExpect([mock someMethod]);

/* run code under test */

OCMVerifyAll(); // will complain that someMethod has not been called

OCMVerifyAll requires an argument [mock in this case].

Mocking Class methods with Macro Syntax results in original implementation Called

I just can't get Class method mocking to work with the new syntax. This will work fine:

TABCoreDataBulkOperations *bulkOperations = OCMClassMock(TABCoreDataBulkOperations.class);
[[[[(id)bulkOperations stub] classMethod] andReturn:@"FOOBAR"] bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY];

Any combination of the Macro based stubbing will result in either compiler errors, or the original implementation being called with OCMock constraints passed as arguments from the invocation.

OCMStub(ClassMethod([bulkOperations.class bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY])).andReturn(@"FOOBAR"); //Original method called
OCMStub([bulkOperations.class bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY]).andReturn(@"FOOBAR"); //Original method called
OCMStub(ClassMethod([TABCoreDataBulkOperations bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY])).andReturn(@"FOOBAR"); //Original method called
OCMStub(ClassMethod([TABCoreDataBulkOperations.class bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY])).andReturn(@"FOOBAR"); //Original method called
OCMStub([bulkOperations bulkOperationsOnManagedObjectClass:OCMOCK_ANY withCoreData:OCMOCK_ANY]).andReturn(@"FOOBAR"); //Compiler error

Is there something that I'm doing wrong here? It seems that one of these variants should result in the stub being assigned. The backtrace shows that the class mock is being hit, then running the invocation against the real object:

frame #3: 0x0bea54d5 Redacted`-[OCClassMockObject forwardInvocationForClassObject:](self=0x0bf0dd50, _cmd=0x01dfc71b, anInvocation=0x13c578f0) + 293 at OCClassMockObject.m:128

From the docs on OCMock.org, this should be working in master since M1.

No OCMReject?

I'm curious why there isn't an OCMReject to match the OCMExpect. We have to revert to the old syntax for rejects.

Weak pointer becomes nil after creating partial mock

I am in the process of migrating to OCMock 3, but I have run into a problem where a weak pointer on an object becomes nil after I create a partial mock for the pointed-to object. I have reproduced the behavior in a simple test case.

Am I misusing OCMock? This sort of usage has not been a problem with OCMock 2.

So far, I have seen this with Xcode 5.1.1 on OS X 10.9.4 when using the iOS simulator. It happens with both the 32-bit and 64-bit simulators.

Segmentation fault when implementing a stub with andDo

I'm writing test cases for code based on AFNetworking and using OCMock to do this. If I implement my stub like this:

    OCMStub([mockRemoteStore POST:[OCMArg any] parameters:[OCMArg any] success:[OCMArg any] failure:[OCMArg any]]).andCall(self, @
            selector(POST:parameters:success:failure:));
- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
                       success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                       failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure {
    if (failure) {
        ExHTTPRemoteDataStore *remoteStore = [TestStore store].remoteHTTPDataStore;
        NSError *error = [NSError errorWithDomain:@"Mock Error Domain" code:1234 userInfo:@{}];
        failure(nil, error);
    }
    return nil;
}

Everything works as expected.

But if I use .andDo(...):

    OCMStub([mockRemoteStore POST:[OCMArg any] parameters:[OCMArg any] success:[OCMArg any] failure:[OCMArg any]]).andDo(^(NSInvocation *invocation) {
        [self handlePOSTInvocation:invocation];
    });
- (void)handlePOSTInvocation:(NSInvocation *)invocation {
    ExHTTPRemoteDataStore *remoteStore = [TestStore store].remoteHTTPDataStore;
    AFNDataTaskSuccessBlock successBlock = nil;
    AFNDataTaskFailureBlock failureBlock = nil;
    [invocation getArgument:&successBlock atIndex:4];
    [invocation getArgument:&failureBlock atIndex:5];
    NSError *error = [NSError errorWithDomain:@"Mock Error Domain" code:1234 userInfo:@{}];
    failureBlock(nil, error);
    NSURLSessionDataTask *task = nil;
    [invocation setReturnValue:&task];

}

The segmentation fault occurs after/during the call to the failure block. I can't really pinpoint the actual error, but it certainly has to do with either the way I used the NSInvocation *invocation or something in OCMock. I'm using the latest code from the Master branch (downloaded on Aug 6). Is there something I'm obviously doing wrong?

OCMock 3: Infinite recursion when mocking object that does selector forwarding

The code base I work on includes several classes that utilize selector forwarding. Each forwarding class has the following code:

- (BOOL)respondsToSelector:(SEL)aSelector
{
    return [super respondsToSelector:aSelector] || [self.otherObject respondsToSelector:aSelector];
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    if ([self.otherObject respondsToSelector:aSelector])
    {
        return self.otherObject;
    }
    else
    {
        return [super forwardingTargetForSelector:aSelector];
    }
}

When migrating to OCMock 3 from version 2, I found that infinite recursion would occur if I simply created a partial mock for an instance of one of these classes. I worked around it by changing the first line of ‑forwardingTargetForSelector: to be the following:

    if ([_otherObject respondsToSelector:aSelector])

I made a simple test class that demonstrates the problem.

OCMObserverMockObject doesn't have a reject method

I have some code which should only post a notification under certain circumstances. While observer mocks work great for testing if a notification was posted, they don't work for testing that a notification wasn't sent as they lack a -reject method.

Can't mock class method in Pod target

I am trying to mock static method in AFDownloadRequestOperation class (which is in Pods target)

id requestOperation = [OCMockObject mockForClass:[AFDownloadRequestOperation class]];
[[[[requestOperation stub] classMethod]andReturn:@"/Volumes/test5M"] cacheFolder];

In test file when I am trying to invoke this method, result is predictably correct, but when I am invoking this method in project target it turns out that method cacheFolder doesn't return @"/Volumes/test5M".

Is there any known issue that OCMock can't stub class methods in Pods target?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.