Skip to content

Instantly share code, notes, and snippets.

@awalter
Last active October 9, 2015 11:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awalter/99c665d74cf0b614b9ae to your computer and use it in GitHub Desktop.
Save awalter/99c665d74cf0b614b9ae to your computer and use it in GitHub Desktop.
Project for reproduction of shared pointer issue seen in OCMock 3.1 & 3.2 https://github.com/erikdoe/ocmock/issues/254
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#include "someCplusplusfile.hpp"
#endif
@interface AnMMFile : NSObject
@property (readonly) NSString *name;
-(id) init;
#ifdef __cplusplus
@property (readonly) std::shared_ptr<someCplusplusfile> someCplusplusfile;
#endif
-(NSString*) getInternalString;
@end
#import "AnMMFile.h"
@implementation AnMMFile {
std::shared_ptr<someCplusplusfile> _someCplusplusfile;
NSString *_name;
}
- (id)init {
if ((self = [super init])) {
_someCplusplusfile = std::make_shared<someCplusplusfile>();
_name = @"someName";
}
return self;
}
-(NSString*) getInternalString {
return [NSString stringWithCString:_someCplusplusfile->getId().c_str() encoding:[NSString defaultCStringEncoding]];
}
- (std::shared_ptr<someCplusplusfile>)someCplusplusfile {
return _someCplusplusfile;
}
@end
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import "AnMMFile.h"
#import "someCplusplusfile.hpp"
@interface SharedPointerIssueTests : XCTestCase
@end
@implementation SharedPointerIssueTests
- (void)testNoMock_alwaysPasses {
AnMMFile *anmmFile = [[AnMMFile alloc] init];
// both pass
XCTAssertEqualObjects(anmmFile.name, @"someName"); // calls in mm file
XCTAssertEqualObjects([anmmFile getInternalString], @"someString"); // calls through to cpp file
// gets shared pointer ok
std::shared_ptr<someCplusplusfile> aNativeObject = anmmFile.someCplusplusfile;
std::string nativeString = aNativeObject->getId();
// passes
XCTAssertEqualObjects([NSString stringWithCString:nativeString.c_str() encoding:[NSString defaultCStringEncoding]], @"someString");
}
- (void)testMock_badAccessFor3 {
AnMMFile *anmmFile = [[AnMMFile alloc] init];
// gets shared pointer ok
std::shared_ptr<someCplusplusfile> aNativeObject = anmmFile.someCplusplusfile;
std::string nativeString = aNativeObject->getId();
// passes
XCTAssertEqualObjects([NSString stringWithCString:nativeString.c_str() encoding:[NSString defaultCStringEncoding]], @"someString");
// ****** problems start here, when we partial mock *****
id partialMock = [OCMockObject partialMockForObject:anmmFile];
// same results if we use the new sytax for 3.x
//id partialMock = OCMPartialMock(anmmFile);
// these still pass ok
XCTAssertEqualObjects(anmmFile.name, @"someName"); // calls in mm file
XCTAssertEqualObjects([anmmFile getInternalString], @"someString"); // calls through to cpp file
XCTAssertEqualObjects(((AnMMFile *)partialMock).name, @"someName"); // calls in mm file
XCTAssertEqualObjects([((AnMMFile *)partialMock) getInternalString], @"someString"); // calls through to cpp file
// line below fails with a EXC_BAD_ACCESS for OCMock 3.1.x & 3.2, does not fail for OCMock 2.2.x
std::shared_ptr<someCplusplusfile> aNativeObject2 = anmmFile.someCplusplusfile;
std::string nativeString2 = aNativeObject->getId();
// passes for 2.2.x, does not get here for 3.x
XCTAssertEqualObjects([NSString stringWithCString:nativeString2.c_str() encoding:[NSString defaultCStringEncoding]], @"someString");
}
@end
#include "someCplusplusfile.hpp"
std::string someCplusplusfile::getId()
{
return "someString";
}
#ifndef someCplusplusfile_hpp
#define someCplusplusfile_hpp
#include <string>
class someCplusplusfile
{
public:
someCplusplusfile(){}
~someCplusplusfile(){}
std::string getId();
};
#endif /* someCplusplusfile_hpp */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment