单元测试似乎一直是我难以理解的东西,但我可以看出它为什么很重要,并且如果你知道如何使用,它可以节省大量时间。我希望有人能给我指点方向。
我有以下的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
的实例,我可以创建一个类别(category),其中有一个方法,仅假装通知被触发并调用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
现在该测试已经通过了,但是这是否是测试的正确/最佳方式呢?