Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fulfill Expectation in an asynchronous Test #84

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion OCMockito.podspec
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.8'
s.source = { :git => 'https://github.com/jonreid/OCMockito.git', :tag => 'v1.3.1' }
s.source_files = 'Source/OCMockito/OCMockito.h', 'Source/OCMockito/**/*.{h,m}', 'Source/ThirdParty/**/*.{h,m}'
s.public_header_files = 'Source/OCMockito/OCMockito.h', 'Source/OCMockito/MKTArgumentCaptor.h', 'Source/OCMockito/MKTBaseMockObject.h', 'Source/OCMockito/MKTClassObjectMock.h', 'Source/OCMockito/MKTObjectMock.h', 'Source/OCMockito/MKTObjectAndProtocolMock.h', 'Source/OCMockito/MKTProtocolMock.h', 'Source/OCMockito/MKTOngoingStubbing.h', 'Source/OCMockito/MKTPrimitiveArgumentMatching.h'
s.public_header_files = 'Source/OCMockito/OCMockito.h', 'Source/OCMockito/MKTArgumentCaptor.h', 'Source/OCMockito/MKTBaseMockObject.h', 'Source/OCMockito/MKTClassObjectMock.h', 'Source/OCMockito/MKTObjectMock.h', 'Source/OCMockito/MKTObjectAndProtocolMock.h', 'Source/OCMockito/MKTProtocolMock.h', 'Source/OCMockito/MKTOngoingStubbing.h', 'Source/OCMockito/MKTPrimitiveArgumentMatching.h', 'Source/OCMockito/MKTExpectation.h'
s.requires_arc = true
s.dependency 'OCHamcrest', '~> 4.0'
end
6 changes: 6 additions & 0 deletions Source/OCMockito.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -320,6 +320,8 @@
BB333F57C54A0E34C3F7CDB8 /* MKTUnsignedIntArgumentGetter.h in Headers */ = {isa = PBXBuildFile; fileRef = BB33346EC07C56575E551305 /* MKTUnsignedIntArgumentGetter.h */; };
BB333F63D0F00C7A42A34088 /* MKTDoubleReturnSetter.h in Headers */ = {isa = PBXBuildFile; fileRef = BB3333F97110B2D36E738BF6 /* MKTDoubleReturnSetter.h */; };
BB333FCE623D5D9B1AD438C5 /* MKTFloatArgumentGetter.h in Headers */ = {isa = PBXBuildFile; fileRef = BB333452F4E41AD2C02AF623 /* MKTFloatArgumentGetter.h */; };
F66B750019E5DDF700CFB1BF /* MKTExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = F66B74FF19E5DDF700CFB1BF /* MKTExpectation.h */; };
F66B750119E5DDF700CFB1BF /* MKTExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = F66B74FF19E5DDF700CFB1BF /* MKTExpectation.h */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
@@ -510,6 +512,7 @@
BB333F66536CCB4FDAF69E70 /* MKTUnsignedIntArgumentGetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKTUnsignedIntArgumentGetter.m; sourceTree = "<group>"; };
BB333FD90D0AC9CC97708743 /* MKTShortReturnSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKTShortReturnSetter.h; sourceTree = "<group>"; };
BB333FF000A3BE337BA9210D /* MKTUnsignedCharArgumentGetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKTUnsignedCharArgumentGetter.m; sourceTree = "<group>"; };
F66B74FF19E5DDF700CFB1BF /* MKTExpectation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKTExpectation.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
@@ -633,6 +636,7 @@
0827E8551352BC1D00C39A57 /* MKTVerificationData.h */,
0827E86D1353E30400C39A57 /* MKTVerificationData.m */,
0827E8521352BBBC00C39A57 /* MKTVerificationMode.h */,
F66B74FF19E5DDF700CFB1BF /* MKTExpectation.h */,
BB3336ACE4225D6B90159620 /* NSInvocation+OCMockito.h */,
BB33364DC41A888C0E0DA542 /* NSInvocation+OCMockito.m */,
BB3338A6F173CED78B579087 /* Helpers */,
@@ -843,6 +847,7 @@
BB33380B69FC10DAA80D190D /* MKTCharArgumentGetter.h in Headers */,
BB3333A1510034D754E0947C /* MKTClassArgumentGetter.h in Headers */,
BB333D3427B143DFF5630DD4 /* MKTDoubleArgumentGetter.h in Headers */,
F66B750119E5DDF700CFB1BF /* MKTExpectation.h in Headers */,
BB333B6C10A2C74C0E381F14 /* MKTFloatArgumentGetter.h in Headers */,
BB333D4E7022E1357B4D139E /* MKTIntArgumentGetter.h in Headers */,
BB3330A161621C7F164A4F54 /* MKTLongArgumentGetter.h in Headers */,
@@ -911,6 +916,7 @@
BB333DBDD868DC57E7A15AC8 /* MKTCharArgumentGetter.h in Headers */,
BB33305B70FC77AEC3A74B3F /* MKTClassArgumentGetter.h in Headers */,
BB3339C6912270DE2DAB8FBF /* MKTDoubleArgumentGetter.h in Headers */,
F66B750019E5DDF700CFB1BF /* MKTExpectation.h in Headers */,
BB333FCE623D5D9B1AD438C5 /* MKTFloatArgumentGetter.h in Headers */,
BB33323A9923F1CC2DF3BA52 /* MKTIntArgumentGetter.h in Headers */,
BB333725C1608C4EF5448E58 /* MKTLongArgumentGetter.h in Headers */,
7 changes: 7 additions & 0 deletions Source/OCMockito/MKTBaseMockObject.m
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ - (void)forwardInvocation:(NSInvocation *)invocation
return;
[self prepareInvocationForStubbing:invocation];
[self answerInvocation:invocation];
[self fulfillExpectationForInvocation:invocation];
}

- (BOOL)handlingVerifyOfInvocation:(NSInvocation *)invocation
@@ -103,6 +104,12 @@ - (void)useExistingAnswerInStub:(MKTStubbedInvocationMatcher *)stub forInvocatio
[invocation mkt_setReturnValue:stub.answer];
}

- (void)fulfillExpectationForInvocation:(NSInvocation *)invocation
{
MKTStubbedInvocationMatcher *stubbedInvocation = [self.invocationContainer findAnswerFor:invocation];
if (stubbedInvocation.expectation)
[stubbedInvocation.expectation fulfill];
}

#pragma mark MKTPrimitiveArgumentMatching

13 changes: 13 additions & 0 deletions Source/OCMockito/MKTExpectation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// MKTExpectation.h
// OCMockito
//
// Created by Tobias Kräntzer on 08.10.14.
// Copyright (c) 2014 Jonathan M. Reid. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol MKTExpectation <NSObject>
- (void)fulfill;
@end
2 changes: 2 additions & 0 deletions Source/OCMockito/MKTInvocationContainer.h
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
@class MKTInvocationMatcher;
@class MKTStubbedInvocationMatcher;
@protocol HCMatcher;
@protocol MKTExpectation;


@interface MKTInvocationContainer : NSObject
@@ -21,5 +22,6 @@
- (void)setInvocationForPotentialStubbing:(NSInvocation *)invocation;
- (void)setMatcher:(id <HCMatcher>)matcher atIndex:(NSUInteger)argumentIndex;
- (void)addAnswer:(id)answer;
- (void)addExpectation:(id<MKTExpectation>)expectation;
- (MKTStubbedInvocationMatcher *)findAnswerFor:(NSInvocation *)invocation;
@end
8 changes: 8 additions & 0 deletions Source/OCMockito/MKTInvocationContainer.m
Original file line number Diff line number Diff line change
@@ -55,6 +55,14 @@ - (void)addAnswer:(id)answer
[self.stubbed insertObject:self.invocationForStubbing atIndex:0];
}

- (void)addExpectation:(id<MKTExpectation>)expectation
{
[_registeredInvocations removeLastObject];

self.invocationForStubbing.expectation = expectation;
[self.stubbed insertObject:self.invocationForStubbing atIndex:0];
}

- (MKTStubbedInvocationMatcher *)findAnswerFor:(NSInvocation *)invocation
{
for (MKTStubbedInvocationMatcher *s in self.stubbed)
4 changes: 4 additions & 0 deletions Source/OCMockito/MKTOngoingStubbing.h
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>
#import "MKTPrimitiveArgumentMatching.h"
#import "MKTExpectation.h"

@class MKTInvocationContainer;

@@ -71,4 +72,7 @@
/// Stubs given @c double as return value.
- (MKTOngoingStubbing *)willReturnDouble:(double)value;

/// Add expectation matcher to the stub.
- (MKTOngoingStubbing *)willFulfill:(id<MKTExpectation>)expectation;

@end
5 changes: 5 additions & 0 deletions Source/OCMockito/MKTOngoingStubbing.m
Original file line number Diff line number Diff line change
@@ -131,6 +131,11 @@ - (MKTOngoingStubbing *)willReturnDouble:(double)value
return self;
}

- (MKTOngoingStubbing *)willFulfill:(id<MKTExpectation>)expectation
{
[self.invocationContainer addExpectation:expectation];
return self;
}

#pragma mark MKTPrimitiveArgumentMatching

2 changes: 2 additions & 0 deletions Source/OCMockito/MKTStubbedInvocationMatcher.h
Original file line number Diff line number Diff line change
@@ -7,10 +7,12 @@
//

#import "MKTInvocationMatcher.h"
#import "MKTExpectation.h"


@interface MKTStubbedInvocationMatcher : MKTInvocationMatcher

@property (nonatomic, strong) id answer;
@property (nonatomic, strong) id<MKTExpectation> expectation;

@end
15 changes: 15 additions & 0 deletions Source/OCMockito/OCMockito.h
Original file line number Diff line number Diff line change
@@ -234,3 +234,18 @@ FOUNDATION_EXPORT id MKTAtLeastOnce(void);
#ifdef MOCKITO_SHORTHAND
#define atLeastOnce() MKTAtLeastOnce()
#endif


// Enable support of expectation matching.
#ifdef MOCKITO_EXPECTATION

@interface XCTestExpectation () <MKTExpectation>
@end

#define MKTGiven(methodCall) MKTGivenWithLocation(self, __FILE__, __LINE__, ^{methodCall; return @YES;}())

#ifdef MOCKITO_SHORTHAND
#define expectation(message) [self expectationWithDescription:message]
#endif

#endif
10 changes: 10 additions & 0 deletions Source/Tests/StubObjectTests.m
Original file line number Diff line number Diff line change
@@ -384,4 +384,14 @@ - (void)testStubbingProperty_ShouldStubValueForKeyPath_SoSortDescriptorsWork
assertThat(sortedArray, contains(sameInstance(obj1), sameInstance(obj2), nil));
}

- (void)testStubbedMethodFulfillExpectation_ShouldCallFulfill
{
id expectation = mockProtocol(@protocol(MKTExpectation));

[[given([mockObject methodReturningObject]) willReturn:@"STUBBED"] willFulfill:expectation];
assertThat([mockObject methodReturningObject], is(@"STUBBED"));

[verifyCount(expectation, times(1)) fulfill];
}

@end