views:

118

answers:

3

Is NSInvocation class not meant to be called via unit tests (for iPhone)?

My intent is to call a class's method generically and since the method has more than 2 parameters, I can't use [myTestClass performSelector:withObject:withObject]

Instead, I'm trying to use NSInvocation but as soon as I try to instantiate from NSInvocation class, I get the build error:

2009-12-31 11:12:16.380 otest[2562:903] * ABOUT TO CALL NSInvocation /Developer/Tools/RunPlatformUnitTests.include: line 415: 2562 Bus error
"${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}" /Developer/Tools/RunPlatformUnitTests.include:451: error: Test rig '/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/ iPhoneSimulator3.1.2.sdk/Developer/usr/bin/otest' exited abnormally with code 138 (it may have crashed).

My class under test:

@implementation MyExampleClass
-(void)methodWithArgs:(NSString *)aValue 
          secondParam:(NSString *)aSecond 
          thirdParam:(NSString *)aThird
{
    NSLog(@"methodWithArgs reached");
}
-(void)methodBlank
{
    NSLog(@"methodBlank reached");
}
-(void)isTesting
{
    NSLog(@"isTesting reached");
}
@end

My unit test:

@interface MyClassTests : SenTestCase
{
}    
@end

@implementation MyClassTests

- (void)testNSInvocation
{   
    Class probeClass = NSClassFromString(@"MyExampleClass");
    if (probeClass != Nil) {        
      SEL selector = NSSelectorFromString(@"isTesting");

      NSMethodSignature *sig = [probeClass methodSignatureForSelector:selector];

      // the following line causes the error
      NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];  

      // this variation also fails
      NSMethodSignature *sig2 = [probeClass 
      methodSignatureForSelector:@selector(methodWithArgs:secondParam:thirdParam:)];

      NSInvocation *inv2 = [NSInvocation invocationWithMethodSignature:sig2];   
    }   
}
@end

What's a way to invoke a method with more than 2 parameters at run-time? Do I have to change the signature of the method so it only has 2 params? Is this a limitation of the unit-test framework?

+1  A: 

NSInvocation should work fine within a test harness. SenTest doesn't muck with it at all.

2562 Bus error

This indicates that the process has crashed. Hard.

Run the test harness in the debugger and grab the stack trace. Off-hand, I would suggest that you test to make sure that sig is non-nil.

bbum
A: 

Are you using the right selector? You have indicated the test is going to call a method isTesting in MyExampleClass, with no arguments... like bbum notes, it seems likely that selector is not right and therefor sig is nil and then invocation creation dies. You should at least check for that case and not call if it is so.

Kendall Helmstetter Gelner
I've added code to show what my class under test looks like -- I think I'm calling the selector correctly and also tried out a second selector that refers to a method with multiple arguments. Both of them produce errors (one set is commented out when I try the other)
Alexi Groove
A: 

The reason the above is failing is indeed due to an incorrect selector.

Instead of using "methodSignatureForSelector", I needed to specify: "instanceMethodSignatureForSelector"

since the methods are instance methods.

However, both of your answers were helpful in tracking down the issue.

Alexi Groove
Glad you figured it out!
Kendall Helmstetter Gelner