2016-09-20 75 views
3

我的代码调用C库函数:在我的情况下使用未声明的标识符错误

@implementation Store 
    ... 
    -(void) doWork { 
    // this is a C function from a library 
    int data = getData(); 
    ... 
    } 
end 

我的单元测试上述功能,我想嘲笑C函数getData()在我的测试,这里是我的测试案例:

@interface StoreTests : XCTestCase { 
    int mData; 
    Store *store; 
} 
@end 

@implementation StoreTests 

-(void) setUp { 
    [super setUp]; 
    mData = 0; 
    store = [[Store alloc] init]; 
} 

-(void) testDoWork { 
    // this call will use the mocked getData(), no problem here. 
    [store doWork]; 
} 

// mocked getData() 
int getData() { 
    mData = 10; // Use of undeclared identifier 'mData', why? 
    return mData; 
} 

... 
@end 

为什么我收到编译错误: Use of undeclared identifier 'mData'里面嘲笑getData()功能?

+0

' - (INT)的getData(){' – ozgur

+0

不,如果我变成' - (INT)的getData(){',我得到奇怪的编译器错误'期待的功能body',我当前的代码工作得很好,模拟的功能由生产代码调用。只有当我将模拟函数中的mData赋值时才会出现问题。再次,它是一个C函数。 –

+1

我明白你的意思了,我试了一下,然后我写了上面的评论。 –

回答

1

你误会实例方法和变量是如何工作的。

每个实例方法具有可变self它引用当前实例(或“当前对象”)和使用一个实例变量,如mData,是用于使用self访问该变量的简写,例如self->mData,其中->是用于字段访问的(Objective-)C操作符。所以,你的setup方法写入“长手”:

-(void) setUp { 
    [super setUp]; 
    self->mData = 0; 
    self->store = [[Store alloc] init]; 
} 

但在哪里呢self,将参考实例,本身从何而来?那么这不是神奇的,只是隐藏,它会自动作为隐藏的额外参数传递给实例方法。 在这一点上切换到伪代码来显示这一点。setup方法有效编译为:

-(void) setUp withSelf:(StoreTest *)self { 
    [super setUp]; 
    self->mData = 0; 
    self->store = [[Store alloc] init]; 
} 

以及诸如电话:

StoreTests *myStoreTests = ... 

[myStoreTests setup]; 

有效编译,就像这样:

[myStoreTests setup withSelf:myStoreTests]; 

自动添加额外self论据。

现在所有上述仅适用于方法,并且使他们能够访问实例变量和方法,它并不适用于普通的C函数 - 他们有没有隐藏self参数,不能访问实例变量。

在你所添加的声明的接口mData之外的答案提到的解决方案:

int mData; 
@interface StoreTests : XCTestCase { 
    Store *store; 
} 
@end 

改变mData全局变量,而不是作为一个实例变量。 C函数可以访问全局变量。然而,这确实意味着该类的每个实例共享相同的mData,在这种情况下只有一个mData而不是每个实例一个。

因此,将一个实例变量放到一个全局中并不是解决这个问题的一般方法,但是因为你不可能有一个以上的StoreTests类的实例,所以在这种情况下它是一个合适的解决方案。

你应该然而让一个变化:你只能有一个程序给出名称的全局变量,所以你mData必须是唯一的,是你的程序中通过任何代码访问,不只是的StoreTests代码。您可以缓解此我声明变量为static

static int mData; 

这保持变量作为全局,但只使它同文件的声明,这也许是StoreTests只是在代码中可见的代码。

HTH

+0

非常没有吸引力。谢谢! –

0

我发现我的问题的一个解决方案,那就是宣布mData以上@interface StoreTests : XCTestCase,这样的事情:

int mData; 
@interface StoreTests : XCTestCase { 
    Store *store; 
} 
@end 
... 
相关问题