Skip to content

Instantly share code, notes, and snippets.

@artemstepanenko
Last active September 10, 2016 09:23
Show Gist options
  • Save artemstepanenko/5bf1cf5efbc6cba1e1933081da9a4494 to your computer and use it in GitHub Desktop.
Save artemstepanenko/5bf1cf5efbc6cba1e1933081da9a4494 to your computer and use it in GitHub Desktop.
//
// CatalogPresenterTests.m
// PresentationUnitTestingTests
//
// Created by Artem Stepanenko on 17/08/16.
// Copyright © 2016 Artem Stepanenko. All rights reserved.
//
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import "TestingHelper.h"
#import "CatalogPresenter.h"
#import "CatalogViewProtocol.h"
#import "Router.h"
#import "SKRNetworking.h"
#import "SKRError.h"
#import "SKRItem.h"
@interface CatalogPresenterTests : XCTestCase
// these objects will be mocked,
// meaning any of their code won't be executed
@property (nonatomic) id<CatalogViewProtocol> mockView;
@property (nonatomic) Router *mockRouter;
@property (nonatomic) SKRNetworking *mockNetworking;
// system under test – only this object is going to be REAL
@property (nonatomic) CatalogPresenter *presenter;
@end
@implementation CatalogPresenterTests
// `setUp` is called right before each testcase method:
// we configure all involved objects from scratch
// to clear side effects from the previously executed testcases
- (void)setUp
{
[super setUp];
// mock objects
self.mockView = OCMProtocolMock(@protocol(CatalogViewProtocol));
self.mockRouter = OCMClassMock([Router class]);
self.mockNetworking = OCMClassMock([SKRNetworking class]);
// system under test – the catalog screen
self.presenter = [[CatalogPresenter alloc] initWithView:self.mockView
router:self.mockRouter
networking:self.mockNetworking];
}
- (void)testThatItemsAreRequestedIfThereAreNone
{
// we notify the screen that it's about to be shown
[self.presenter viewWillAppear];
// and verify if it fetches items
OCMVerify([self.mockNetworking fetchAllItemsWithSuccess:[OCMArg any] failure:[OCMArg any]]);
}
- (void)testThatShowsCartWhenCartButtonTapped
{
// we simulate a user's tap on the cart button
[self.presenter cartTapped];
// and verify if the screen shows a cart screen
OCMVerify([self.mockRouter presentCart]);
}
- (void)testThatNoConnectionAlertAppearsIfErrorReceived
{
// we mock the networking to make it return always 'no connection'
// when items are requested
OCMStub([self.mockNetworking fetchAllItemsWithSuccess:[OCMArg any] failure:[OCMArg any]]).andDo(^(NSInvocation *invocation) {
void (^failureBlock)(SKRError *error);
[invocation getArgument:&failureBlock atIndex:3];
failureBlock([SKRError errorWithMessage:@"No internet" type:SKRErrorTypeNoInternet]);
});
// then simulate an appearance event
[self.presenter viewWillAppear];
// and verify whether the screen shows 'no connection' alert
OCMVerify([self.mockView showNoConnection]);
}
- (void)testThatReloadsViewWhenProductsReceived
{
// we mock the networking so it responds with a list of one item
[self setUpNetworkingToReturnOneProduct];
// then send an apearance event to the cart screen
[self.presenter viewWillAppear];
// and verify that it reloads products
// when they are received
OCMVerify([self.mockView reloadProducts]);
}
- (void)testThatShowsRightAmountOfProductsWhenFetched
{
// we mock the networking to return one item
[self setUpNetworkingToReturnOneProduct];
// notify the screen about it's appearance
[self.presenter viewWillAppear];
// and verify if it really contains a single product
NSUInteger expectedAmount = 1;
NSUInteger actualAmount = self.presenter.products.count;
XCTAssertEqual(expectedAmount, actualAmount, @"The amount of products must be 1");
}
- (void)testThatShowsRightProductName
{
// so the networking gives the cart screen one item
[self setUpNetworkingToReturnOneProduct];
// the screen knows, it's going to be shown
[self.presenter viewWillAppear];
// we verify if the first products name is '911 Turbo S'
NSString *expectedName = @"911 Turbo S";
NSString *actualName = self.presenter.products.firstObject.name;
XCTAssertEqualObjects(expectedName, actualName, @"The product name must be '911 Turbo S'");
}
- (void)testThatReloadsViewWhenUserSearches
{
// the networking is mocked to return the item
[self setUpNetworkingToReturnOneProduct];
// the screen is notified and gets the item under the hood
[self.presenter viewWillAppear];
// we simulate the user searches for 'Tesla'
[self.presenter searchQueryChanged:@"Tesla"];
// and finally verify that the products are reloaded
OCMVerify([self.mockView reloadProducts]);
}
- (void)testThatThereAreNoResultsWhenUserSearchesTesla
{
// the networking returns the single item
[self setUpNetworkingToReturnOneProduct];
// the screen knows it's going to be shown
[self.presenter viewWillAppear];
// the user searches for 'Tesla'
[self.presenter searchQueryChanged:@"Tesla"];
// we expect the amount of search results to be zero
// since there's only '911 Turbo S' in the list
NSUInteger expectedAmount = 0;
NSUInteger actualAmount = self.presenter.products.count;
XCTAssertEqual(expectedAmount, actualAmount, @"The amount of Tesla-s must be zero");
}
- (void)testThatThereIsOneProductWhenUserSearches911
{
// ...the item
[self setUpNetworkingToReturnOneProduct];
// ...the notification
[self.presenter viewWillAppear];
// the user's search query is '911'
[self.presenter searchQueryChanged:@"911"];
// so the search results must contain '911 Turbo S'
NSUInteger expectedAmount = 1;
NSUInteger actualAmount = self.presenter.products.count;
XCTAssertEqual(expectedAmount, actualAmount, @"There must be '911 Turbo S' in the search results");
}
#pragma mark - Private
- (void)setUpNetworkingToReturnOneProduct
{
NSDictionary *productDictionary = [TestingHelper someProductDictionary];
OCMStub([self.mockNetworking fetchAllItemsWithSuccess:[OCMArg any] failure:[OCMArg any]]).andDo(^(NSInvocation *invocation) {
void (^successBlock)(NSArray *responseObject);
[invocation getArgument:&successBlock atIndex:2];
successBlock(@[productDictionary]);
});
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment