Skip to content

Commit b389f9e

Browse files
committed
add error handling test and error cases
1 parent 679d152 commit b389f9e

File tree

3 files changed

+22
-25
lines changed

3 files changed

+22
-25
lines changed

MVVMPlayground/MVVMPlayground/Module/PhotoList/PhotoListViewController.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class PhotoListViewController: UIViewController {
1515
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
1616

1717
lazy var viewModel: PhotoListViewModel = {
18-
return PhotoListViewModel(apiService: APIService())
18+
return PhotoListViewModel()
1919
}()
2020

2121
override func viewDidLoad() {
@@ -69,6 +69,8 @@ class PhotoListViewController: UIViewController {
6969
self?.tableView.reloadData()
7070
}
7171
}
72+
73+
viewModel.initFetch()
7274

7375
}
7476

MVVMPlayground/MVVMPlayground/Module/PhotoList/PhotoListViewModel.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,9 @@ class PhotoListViewModel {
4343
var reloadTableViewClosure: (()->())?
4444
var showAlertClosure: (()->())?
4545
var updateLoadingStatus: (()->())?
46-
47-
init( apiService: APIServiceProtocol ) {
46+
47+
init( apiService: APIServiceProtocol = APIService()) {
4848
self.apiService = apiService
49-
initFetch()
5049
}
5150

5251
func initFetch() {
@@ -112,7 +111,6 @@ extension PhotoListViewModel {
112111
}
113112
}
114113

115-
116114
struct PhotoListCellViewModel {
117115
let titleText: String
118116
let descText: String

MVVMPlayground/MVVMPlaygroundTests/PhotoListViewModelTests.swift

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ class PhotoListViewModelTests: XCTestCase {
1313

1414
var sut: PhotoListViewModel!
1515
var mockAPIService: MockApiService!
16-
16+
1717
override func setUp() {
1818
super.setUp()
1919
mockAPIService = MockApiService()
20-
sut = PhotoListViewModel( apiService: mockAPIService )
21-
20+
sut = PhotoListViewModel(apiService: mockAPIService)
2221
}
2322

2423
override func tearDown() {
@@ -27,7 +26,7 @@ class PhotoListViewModelTests: XCTestCase {
2726
super.tearDown()
2827
}
2928

30-
func test_fetch_popular_photo_when_view_is_ready() {
29+
func test_fetch_photo() {
3130
// Given
3231
mockAPIService.completePhotos = [Photo]()
3332

@@ -38,10 +37,9 @@ class PhotoListViewModelTests: XCTestCase {
3837
XCTAssert(mockAPIService!.isFetchPopularPhotoCalled)
3938
}
4039

41-
func test_fetch_fail() {
40+
func test_fetch_photo_fail() {
4241

4342
// Given a failed fetch with a certain failure
44-
mockAPIService.completePhotos = nil
4543
let error = APIError.permissionDenied
4644

4745
// When
@@ -56,7 +54,7 @@ class PhotoListViewModelTests: XCTestCase {
5654

5755
func test_create_cell_view_model() {
5856
// Given
59-
let photos = PhotoStub().stubPhotos()
57+
let photos = StubGenerator().stubPhotos()
6058
mockAPIService.completePhotos = photos
6159
let expect = XCTestExpectation(description: "reload closure triggered")
6260
sut.reloadTableViewClosure = { () in
@@ -102,7 +100,7 @@ class PhotoListViewModelTests: XCTestCase {
102100

103101
//Given a sut with fetched photos
104102
let indexPath = IndexPath(row: 0, section: 0)
105-
sutFinishedFetchPhotos()
103+
goToFetchPhotoFinished()
106104

107105
//When
108106
sut.userPressed( at: indexPath )
@@ -117,7 +115,7 @@ class PhotoListViewModelTests: XCTestCase {
117115

118116
//Given a sut with fetched photos
119117
let indexPath = IndexPath(row: 4, section: 0)
120-
sutFinishedFetchPhotos()
118+
goToFetchPhotoFinished()
121119

122120
let expect = XCTestExpectation(description: "Alert message is shown")
123121
sut.showAlertClosure = { [weak sut] in
@@ -138,10 +136,10 @@ class PhotoListViewModelTests: XCTestCase {
138136
func test_get_cell_view_model() {
139137

140138
//Given a sut with fetched photos
141-
sutFinishedFetchPhotos()
139+
goToFetchPhotoFinished()
142140

143141
let indexPath = IndexPath(row: 1, section: 0)
144-
let testPhoto = mockAPIService.completePhotos![indexPath.row]
142+
let testPhoto = mockAPIService.completePhotos[indexPath.row]
145143

146144
// When
147145
let vm = sut.getCellViewModel(at: indexPath)
@@ -184,22 +182,21 @@ class PhotoListViewModelTests: XCTestCase {
184182

185183
}
186184

185+
//MARK: State control
187186
extension PhotoListViewModelTests {
188-
private func sutFinishedFetchPhotos() {
189-
mockAPIService.completePhotos = PhotoStub().stubPhotos()
187+
private func goToFetchPhotoFinished() {
188+
mockAPIService.completePhotos = StubGenerator().stubPhotos()
190189
sut.initFetch()
191190
mockAPIService.fetchSuccess()
192191
}
193192
}
194193

195-
196-
197194
class MockApiService: APIServiceProtocol {
198195

199196
var isFetchPopularPhotoCalled = false
200197

201-
var completePhotos: [Photo]?
202-
var completeClosure: ((Bool, [Photo], APIError?) -> ())?
198+
var completePhotos: [Photo] = [Photo]()
199+
var completeClosure: ((Bool, [Photo], APIError?) -> ())!
203200

204201
func fetchPopularPhoto(complete: @escaping (Bool, [Photo], APIError?) -> ()) {
205202
isFetchPopularPhotoCalled = true
@@ -208,16 +205,16 @@ class MockApiService: APIServiceProtocol {
208205
}
209206

210207
func fetchSuccess() {
211-
completeClosure!( true, completePhotos ?? [Photo](), nil )
208+
completeClosure( true, completePhotos, nil )
212209
}
213210

214211
func fetchFail(error: APIError?) {
215-
completeClosure!( false, completePhotos ?? [Photo](), error )
212+
completeClosure( false, completePhotos, error )
216213
}
217214

218215
}
219216

220-
class PhotoStub {
217+
class StubGenerator {
221218
func stubPhotos() -> [Photo] {
222219
let path = Bundle.main.path(forResource: "content", ofType: "json")!
223220
let data = try! Data(contentsOf: URL(fileURLWithPath: path))

0 commit comments

Comments
 (0)