@@ -35,6 +35,15 @@ - (NSString *)bar
35
35
@end
36
36
37
37
38
+ @interface TestSubclassWithClassMethods : TestClassWithClassMethods
39
+
40
+ @end
41
+
42
+ @implementation TestSubclassWithClassMethods
43
+
44
+ @end
45
+
46
+
38
47
39
48
@implementation OCMockObjectClassMethodMockingTests
40
49
@@ -59,7 +68,6 @@ - (void)testCanExpectTheSameClassMethodMoreThanOnce
59
68
STAssertEqualObjects (@" mocked-foo2" , [TestClassWithClassMethods foo ], @" Should have stubbed class method 'foo2'." );
60
69
}
61
70
62
-
63
71
- (void )testClassReceivesMethodsAfterStopWasCalled
64
72
{
65
73
id mock = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
@@ -80,6 +88,77 @@ - (void)testClassReceivesMethodAgainWhenExpectedCallOccurred
80
88
STAssertEqualObjects (@" Foo-ClassMethod" , [TestClassWithClassMethods foo ], @" Should have 'unstubbed' method." );
81
89
}
82
90
91
+ - (void )testCanStubClassMethodFromMockForSubclass
92
+ {
93
+ id subclassMock = [OCMockObject mockForClass: [TestSubclassWithClassMethods class ]];
94
+
95
+ [[[[subclassMock stub ] classMethod ] andReturn: @" mocked-subclass" ] foo ];
96
+ STAssertEqualObjects (@" mocked-subclass" , [TestSubclassWithClassMethods foo ], @" Should have stubbed method." );
97
+ STAssertEqualObjects (@" Foo-ClassMethod" , [TestClassWithClassMethods foo ], @" Should not have stubbed method in superclass." );
98
+ }
99
+
100
+ - (void )testSuperclassReceivesMethodsAfterStopWasCalled
101
+ {
102
+ id mock = [OCMockObject mockForClass: [TestSubclassWithClassMethods class ]];
103
+
104
+ [[[[mock stub ] classMethod ] andReturn: @" mocked" ] foo ];
105
+ [mock stopMocking ];
106
+
107
+ STAssertEqualObjects (@" Foo-ClassMethod" , [TestSubclassWithClassMethods foo ], @" Should not have stubbed class method." );
108
+ }
109
+
110
+ - (void )testCanReplaceSameMethodInSubclassAfterSuperclassMockWasStopped
111
+ {
112
+ id superclassMock = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
113
+ id subclassMock = [OCMockObject mockForClass: [TestSubclassWithClassMethods class ]];
114
+
115
+ [[[[superclassMock stub ] classMethod ] andReturn: @" mocked-superclass" ] foo ];
116
+ [superclassMock stopMocking ];
117
+
118
+ [[[[subclassMock stub ] classMethod ] andReturn: @" mocked-subclass" ] foo ];
119
+ STAssertEqualObjects (@" mocked-subclass" , [TestSubclassWithClassMethods foo ], @" Should have stubbed method" );
120
+ }
121
+
122
+ - (void )testCanReplaceSameMethodInSuperclassAfterSubclassMockWasStopped
123
+ {
124
+ id superclassMock = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
125
+ id subclassMock = [OCMockObject mockForClass: [TestSubclassWithClassMethods class ]];
126
+
127
+ [[[[subclassMock stub ] classMethod ] andReturn: @" mocked-subclass" ] foo ];
128
+ [subclassMock stopMocking ];
129
+
130
+ [[[[superclassMock stub ] classMethod ] andReturn: @" mocked-superclass" ] foo ];
131
+ STAssertEqualObjects (@" mocked-superclass" , [TestClassWithClassMethods foo ], @" Should have stubbed method" );
132
+ }
133
+
134
+ // The following test does not verify behaviour; it shows a problem. It only passes when run in
135
+ // isolation because otherwise the other tests cause the problem that this test demonstrates.
136
+
137
+ - (void )_ignore_testShowThatStubbingSuperclassMethodInSubclassLeavesImplementationInSubclass
138
+ {
139
+ // stage 1: stub in superclass affects both superclass and subclass
140
+ id superclassMock = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
141
+ [[[[superclassMock stub ] classMethod ] andReturn: @" mocked-superclass" ] foo ];
142
+ STAssertEqualObjects (@" mocked-superclass" , [TestClassWithClassMethods foo ], @" Should have stubbed method" );
143
+ STAssertEqualObjects (@" mocked-superclass" , [TestSubclassWithClassMethods foo ], @" Should have stubbed method" );
144
+ [superclassMock stopMocking ];
145
+
146
+ // stage 2: stub in subclass affects only subclass
147
+ id subclassMock = [OCMockObject mockForClass: [TestSubclassWithClassMethods class ]];
148
+ [[[[subclassMock stub ] classMethod ] andReturn: @" mocked-subclass" ] foo ];
149
+ STAssertEqualObjects (@" Foo-ClassMethod" , [TestClassWithClassMethods foo ], @" Should NOT have stubbed method" );
150
+ STAssertEqualObjects (@" mocked-subclass" , [TestSubclassWithClassMethods foo ], @" Should have stubbed method" );
151
+ [subclassMock stopMocking ];
152
+
153
+ // stage 3: should be like stage 1, but it isn't (see last assert)
154
+ // This is because the subclass mock can't remove the method added to the subclass in stage 2
155
+ // and instead has to point the method in the subclass to the real implementation.
156
+ id superclassMock2 = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
157
+ [[[[superclassMock2 stub ] classMethod ] andReturn: @" mocked-superclass" ] foo ];
158
+ STAssertEqualObjects (@" mocked-superclass" , [TestClassWithClassMethods foo ], @" Should have stubbed method" );
159
+ STAssertEqualObjects (@" Foo-ClassMethod" , [TestSubclassWithClassMethods foo ], @" Should NOT have stubbed method" );
160
+ }
161
+
83
162
- (void )testStubsOnlyClassMethodWhenInstanceMethodWithSameNameExists
84
163
{
85
164
id mock = [OCMockObject mockForClass: [TestClassWithClassMethods class ]];
0 commit comments