我正在测试的一个类中有两个方法:
- (NSUInteger)sendBuffer:(uint8_t *)buffer length:(NSUInteger)length;
- (BOOL)sendFormattedCommandForAddress:(uint8_t)address
withData:(uint8_t)data
andCommandType:(ZKZSensorCommandType)commandType;-sendFormattedCommandForAddress:withData:andCommandType:构建一个char数组,并将指向该数组的指针传递给-sendBuffer:length:。此数组的内容根据address、data和commandType的不同而不同。在我的测试中,我想验证是否构建了正确的数组并将其传递给-sendBuffer:length:。OCMock不会让我对uint8_t *参数设置期望。OCMockito/OCHamcrest不允许我使用部分模拟。我尝试将-sendBuffer:length:方法与调用我的测试用例类中的方法的方法混合在一起,并对该方法调用设置一个期望。但是,当调用swizzled方法时,self会指向测试中的类,而不是我的测试用例。我可以在我测试的类中持久化buffer,然后在测试中检查这个buffer的内容,但是我讨厌仅仅为了支持测试而在生产代码中添加一些东西。有没有人对如何测试这个行为有更好的建议?
发布于 2013-01-22 04:01:22
虽然这可以说是一个见仁见智的问题,但综合单元测试的好处使得代码复杂性的小幅和包含增量成为一种有价值的权衡。在您描述的情况下,我认为您的想法是向生产类添加一个缓冲区,以便可以在单元测试中检索和断言发送的最后一个字节序列,这是一种非常好的方法。
我个人可能会添加一个布尔属性来控制是否维护缓冲区,只是为了避免在生产代码中发送大型消息时出现任何意外的不必要的内存开销。单元测试设置当然会设置此属性,而应用程序/框架生产代码则不会。同样,关键是要使添加的代码简单到明显正确。:-)
如果您希望或需要严格要求生产类公开的接口,您还可以考虑使缓冲区维护代码依赖于条件编译。我个人更喜欢前一种方法,但各有千秋。
发布于 2013-01-26 14:03:08
你不需要一个模仿框架来制作模仿。我认为,挑战在于您实际上并不想调用-sendBuffer:length:。在这种情况下,只需使用子类和重写方法,如Michael Feather的书Working Effectively with Legacy Code中所述。
由于不知道您的类的名称,我将其称为Sender。这就是我要写的,将它直接放入SenderTest.m:
@interface TestingSender : Sender
@property (assign, nonatomic) NSUInteger sendBufferCount;
@property (assign, nonatomic) uint8_t *sendBufferBuffer;
@property (assign, nonatomic) NSUInteger sendBufferLength;
@end
@implementation TestingSender
- (NSUInteger)sendBuffer:(uint8_t *)buffer length:(NSUInteger)length
{
++_sendBufferCount;
_sendBufferBuffer = buffer;
_sendBufferLength = length;
}
@end然后,测试代码创建一个TestingSender,而不是一个发送者。
https://stackoverflow.com/questions/14444671
复制相似问题