【发布时间】:2014-11-27 14:13:43
【问题描述】:
单元测试只是我似乎永远无法理解的事情,但我可以看到它为什么重要并且可以节省大量时间(如果您知道自己在做什么)。我希望有人能指出我正确的方向。
我有以下UIViewController
QBElectricityBaseVC.h
@interface QBElectricityBaseVC : QBStateVC
@property (nonatomic, strong) QBElectricityUsage *electricityUsage;
@property (nonatomic, assign) CGFloat tabBarHeight;
- (void)updateElectricityUsage;
@end
QBElectricityBaseVC.m
@implementation QBElectricityBaseVC
- (instancetype)init
{
self = [super init];
if (self) {
self.tabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString(@"electricity_title", nil) image:nil tag:0];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.notificationCenter addObserver:self selector:@selector(updateElectricityUsage)
name:kUpdatedElectricityUsageKey object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.notificationCenter removeObserver:self];
}
- (void)updateElectricityUsage
{
self.electricityUsage = [self.stateManager electricityUsage];
}
- (CGFloat)tabBarHeight
{
return self.tabBarController.tabBar.frame.size.height;
}
@end
我应该测试什么?
- 添加了
kUpdatedElectricityUsageKey的观察者 -
self.electricityUsage成为QBElectricityUsage的一个实例 - 返回一个
tabBarHeight -
kUpdatedElectricityUsageKey的观察者被移除
我是否遗漏了我应该测试或测试我真的不应该测试的东西?
如何测试?
所以我尝试使用Specta 和Expexta 来做到这一点。如果我需要模拟任何东西,我会使用OCMockito。
我真的不知道如何测试添加/删除观察者。我在 Expexta 文档中看到以下内容,但不确定它是否相关/如何使用它:
expect(^{ /* code */ }).to.notify(@"NotificationName"); passes if a given block of code generates an NSNotification named NotificationName.
expect(^{ /* code */ }).to.notify(notification); passes if a given block of code generates an NSNotification equal to the passed notification.
要测试self.electricityUsage 是否成为QBElectricityUsage 的实例,我可以创建一个类别,该类别具有一个方法,该方法只是假装已触发通知并调用updateElectricityUsage 方法,但这是最好的方法吗?
至于tabBarHeight,我是否应该只测试它返回一个有效的CGFloat,而不用担心它的值是多少?
更新
我将viewWillAppear 方法更改为如下所示:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self addNotificationObservers];
}
- (void)addNotificationObservers
{
[self.notificationCenter addObserver:self selector:@selector(updateElectricityUsage)
name:kUpdatedElectricityUsageKey object:nil];
}
然后我创建了以下测试:
#import "Specs.h"
#import "QBElectricityBaseVC.h"
#import "ElectricityConstants.h"
SpecBegin(QBElectricityBaseVCSpec)
describe(@"QBElectricityBaseVC", ^{
__block QBElectricityBaseVC *electricityBaseVC;
__block NSNotificationCenter *mockNotificationCenter;
beforeEach(^{
electricityBaseVC = [QBElectricityBaseVC new];
mockNotificationCenter = mock([NSNotificationCenter class]);
electricityBaseVC.notificationCenter = mockNotificationCenter;
});
afterEach(^{
electricityBaseVC = nil;
mockNotificationCenter = nil;
});
it(@"should have a notification observer for updated electricity usage", ^{
[electricityBaseVC addNotificationObservers];
[verify(mockNotificationCenter) addObserver:electricityBaseVC selector:@selector(updateElectricityUsage)
name:kUpdatedElectricityUsageKey object:nil];
});
});
SpecEnd
该测试现在通过了,但这是测试它的正确/最佳方法吗?
【问题讨论】:
-
我有完全相同的问题 - 希望那里有更多的文档。另外,为什么不使用 XCTest?
标签: ios unit-testing tdd bdd expecta