-
Notifications
You must be signed in to change notification settings - Fork 91
Reactive View Model Refactoring & Testing #24
Changes from all commits
19ebfcc
95ef7b5
f4ce1df
6d659ee
7215f7e
667c37c
6e88c35
fd67739
3ba967e
aa3f70c
0d95a1d
ced77bc
4a87330
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // | ||
| // FRPFullSizePhotoViewModelTests.m | ||
| // FRP | ||
| // | ||
| // Created by Ash Furrow on 12/26/2013. | ||
| // Copyright (c) 2013 Ash Furrow. All rights reserved. | ||
| // | ||
|
|
||
| #import <Specta/Specta.h> | ||
| #define EXP_SHORTHAND | ||
| #import <Expecta/Expecta.h> | ||
| #import <OCMock/OCMock.h> | ||
|
|
||
| #import "FRPFullSizePhotoViewModel.h" | ||
| #import "FRPPhotoModel.h" | ||
|
|
||
| @interface FRPFullSizePhotoViewModel () | ||
|
|
||
| -(FRPPhotoModel *)initialPhotoModel; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would declare this in a private header instead, so you're not duplicating it and potentially opening the door to confusing errors in your tests. |
||
|
|
||
| @end | ||
|
|
||
| SpecBegin(FRPFullSizePhotoViewModel) | ||
|
|
||
| describe(@"FRPFullSizePhotomodel", ^{ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This outer |
||
| it (@"should assign correct attributes when initialized", ^{ | ||
| NSArray *model = @[]; | ||
| NSInteger initialPhotoIndex = 1337; | ||
|
|
||
| FRPFullSizePhotoViewModel *viewModel = [[FRPFullSizePhotoViewModel alloc] initWithPhotoArray:model initialPhotoIndex:initialPhotoIndex]; | ||
|
|
||
| expect(model).to.equal(viewModel.model); | ||
| expect(initialPhotoIndex).to.equal(viewModel.initialPhotoIndex); | ||
| }); | ||
|
|
||
| it (@"should return nil for an out-of-bounds photo index", ^{ | ||
| NSArray *model = @[[NSObject new]]; | ||
| NSInteger initialPhotoIndex = 0; | ||
|
|
||
| FRPFullSizePhotoViewModel *viewModel = [[FRPFullSizePhotoViewModel alloc] initWithPhotoArray:model initialPhotoIndex:initialPhotoIndex]; | ||
|
|
||
| id subzeroModel = [viewModel photoModelAtIndex:-1]; | ||
| expect(subzeroModel).to.beNil(); | ||
|
|
||
| id aboveBoundsModel = [viewModel photoModelAtIndex:model.count]; | ||
| expect(aboveBoundsModel).to.beNil(); | ||
| }); | ||
|
|
||
| it (@"should return the correct model for photoModelAtIndex:", ^{ | ||
| id photoModel = [NSObject new]; | ||
| NSArray *model = @[photoModel]; | ||
| NSInteger initialPhotoIndex = 0; | ||
|
|
||
| FRPFullSizePhotoViewModel *viewModel = [[FRPFullSizePhotoViewModel alloc] initWithPhotoArray:model initialPhotoIndex:initialPhotoIndex]; | ||
|
|
||
| id returnedModel = [viewModel photoModelAtIndex:0]; | ||
| expect(returnedModel).to.equal(photoModel); | ||
| }); | ||
|
|
||
| it (@"should return the correct initial photo model", ^{ | ||
| NSArray *model = @[[NSObject new]]; | ||
| NSInteger initialPhotoIndex = 0; | ||
|
|
||
| FRPFullSizePhotoViewModel *viewModel = [[FRPFullSizePhotoViewModel alloc] initWithPhotoArray:model initialPhotoIndex:initialPhotoIndex]; | ||
| id mockViewModel = [OCMockObject partialMockForObject:viewModel]; | ||
|
|
||
| [[[mockViewModel expect] andReturn:model[0]] photoModelAtIndex:initialPhotoIndex]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This kinda comes down to personal testing style, but I detest mocking. I don't think it's representative of your API's behavior to consumers, and smells of poor decomposition if it's really necessary. In this specific case, couldn't you just verify that |
||
|
|
||
| id returnedObject = [mockViewModel initialPhotoModel]; | ||
|
|
||
| expect(returnedObject).to.equal(model[0]); | ||
|
|
||
| [mockViewModel verify]; | ||
| }); | ||
| }); | ||
|
|
||
| SpecEnd | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,22 +10,24 @@ | |
| #import <OCMock/OCMock.h> | ||
|
|
||
| #import "FRPGalleryViewModel.h" | ||
| #import "FRPPhotoImporter.h" | ||
|
|
||
| @interface FRPGalleryViewModel () | ||
|
|
||
| -(RACSignal *)importPhotosSignal; | ||
|
|
||
| @end | ||
|
|
||
| SpecBegin(FRPGalleryViewModel) | ||
|
|
||
| describe(@"FRPGalleryViewModel", ^{ | ||
| beforeAll(^{ | ||
| // This is run once and only once before all of the examples | ||
| // in this group and before any beforeEach blocks. | ||
| }); | ||
|
|
||
| beforeEach(^{ | ||
| // This is run before each example. | ||
| }); | ||
|
|
||
| it(@"should be initialized and call importPhotos", ^{ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this test valuable? In other words, what result are you actually trying to test here? I don't think you care about the actual method call as much as the effect. |
||
| STAssertTrue(false, @"Test not implemented."); | ||
| id mockObject = [OCMockObject mockForClass:[FRPGalleryViewModel class]]; | ||
| [[[mockObject expect] andReturn:[RACSignal empty]] importPhotosSignal]; | ||
|
|
||
| mockObject = [mockObject init]; | ||
|
|
||
| [mockObject verify]; | ||
| [mockObject stopMocking]; | ||
| }); | ||
| }); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably a bit much for your book, but this operation can be written without any state or pesky strongifying:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great idea!