我只是在掌握 TDD 和 mocking 的概念,并且在如何正确处理方面遇到了问题。我有一张下拉表格,让用户创建一个新的核心数据对象并将其保存到数据存储中。我不确定我是否采用了最好的方法来测试它。
- (IBAction)add:(id)sender
{
NSString *itemName = [self.itemNameTextField stringValue];
SGItem *newItem = [NSEntityDescription insertNewObjectForEntityForName:kItemEntityName inManagedObjectContext:[self managedObjectContext]];
newItem.name = itemName;
NSError *error = nil;
BOOL canSaveNewItem = [[self managedObjectContext] save:&error];
if (!canSaveNewItem)
{
[NSApp presentError:error];
}
[self clearFormFields]; // Private method that clears text fields, disables buttons
[NSApp endSheet:[self window] returnCode:NSOKButton];
}
我正在尝试编写两种测试方法来测试这一点:一种测试托管对象无法保存的场景,另一种测试成功保存的场景。
@interface SGAddItemWindowControllerTests : SGTestCase
{
@private
SGAddItemWindowController *addItemWindowController;
id mockApp;
id mockNameField;
}
- (void)setUp
{
mockNameField = [OCMockObject mockForClass:[NSTextField class]];
mockApp = [OCMockObject mockForClass:[NSApplication class]];
addItemWindowController = [[BLAddItemWindowController alloc] init];
[addItemWindowController setValue:mockNameField forKey:@"itemNameTextField"];
}
- (void)testAddingNewItemFromSheetFailed
{
// Setup
NSString *fakeName = @"";
[[[mockNameField expect] andReturn:fakeName] stringValue];
[[mockApp expect] presentError:[OCMArg any]];
// Execute
[addItemWindowController add:nil];
// Verify
[mockApp verify];
}
- (void)testAddingNewItemFromSheetSucceeds
{
// Setup
NSString *fakeName = @"Item Name";
[[[mockNameField expect] andReturn:fakeName] stringValue];
[[mockApp expect] endSheet:[OCMArg any] returnCode:NSOKButton];
// Execute
[addItemWindowController add:nil];
// Verify
[mockApp verify];
[mockNameField verify];
}
@end
以下是我知道我遇到的问题,但不知道如何解决:
- 我不确定如何在测试方面处理托管对象上下文。我应该调出整个核心数据堆栈还是只创建一个模拟
NSManagedObjectContext
? - 仅将文本字段值设置为触发 if 语句的方式的想法似乎是错误的。理想情况下,我认为我应该删除该
save:
方法并返回“是”或“否”,但鉴于问题 1,我不确定这一切的核心数据方面。
我认为我走在正确的轨道上,但我可以就如何解决我的问题使用第二种意见,并让我走上测试代码片段的正确道路。