forked from kudoleh/iOS-Clean-Architecture-MVVM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMoviesQueriesListViewModelTests.swift
113 lines (95 loc) · 3.95 KB
/
MoviesQueriesListViewModelTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
@testable import ExampleMVVM
import XCTest
class MoviesQueriesListViewModelTests: XCTestCase {
private enum FetchRecentQueriedUseCase: Error {
case someError
}
var movieQueries = [MovieQuery(query: "query1"),
MovieQuery(query: "query2"),
MovieQuery(query: "query3"),
MovieQuery(query: "query4"),
MovieQuery(query: "query5")]
class FetchRecentMovieQueriesUseCaseMock: UseCase {
var startCalledCount: Int = 0
var error: Error?
var movieQueries: [MovieQuery] = []
var completion: (Result<[MovieQuery], Error>) -> Void = { _ in }
func start() -> Cancellable? {
if let error = error {
completion(.failure(error))
} else {
completion(.success(movieQueries))
}
startCalledCount += 1
return nil
}
}
func makeFetchRecentMovieQueriesUseCase(_ mock: FetchRecentMovieQueriesUseCaseMock) -> FetchRecentMovieQueriesUseCaseFactory {
return { _, completion in
mock.completion = completion
return mock
}
}
func test_whenFetchRecentMovieQueriesUseCaseReturnsQueries_thenShowTheseQueries() {
// given
let useCase = FetchRecentMovieQueriesUseCaseMock()
useCase.movieQueries = movieQueries
let viewModel = DefaultMoviesQueryListViewModel.make(
numberOfQueriesToShow: 3,
fetchRecentMovieQueriesUseCaseFactory: makeFetchRecentMovieQueriesUseCase(useCase)
)
// when
viewModel.viewWillAppear()
// then
XCTAssertEqual(viewModel.items.value.map { $0.query }, movieQueries.map { $0.query })
XCTAssertEqual(useCase.startCalledCount, 1)
}
func test_whenFetchRecentMovieQueriesUseCaseReturnsError_thenDontShowAnyQuery() {
// given
let useCase = FetchRecentMovieQueriesUseCaseMock()
useCase.error = FetchRecentQueriedUseCase.someError
let viewModel = DefaultMoviesQueryListViewModel.make(
numberOfQueriesToShow: 3,
fetchRecentMovieQueriesUseCaseFactory: makeFetchRecentMovieQueriesUseCase(useCase)
)
// when
viewModel.viewWillAppear()
// then
XCTAssertTrue(viewModel.items.value.isEmpty)
XCTAssertEqual(useCase.startCalledCount, 1)
}
func test_whenDidSelectQueryEventIsReceived_thenCallDidSelectAction() {
// given
let selectedQueryItem = MovieQuery(query: "query1")
var actionMovieQuery: MovieQuery?
var delegateNotifiedCount = 0
let didSelect: MoviesQueryListViewModelDidSelectAction = { movieQuery in
actionMovieQuery = movieQuery
delegateNotifiedCount += 1
}
let viewModel = DefaultMoviesQueryListViewModel.make(
numberOfQueriesToShow: 3,
fetchRecentMovieQueriesUseCaseFactory: makeFetchRecentMovieQueriesUseCase(FetchRecentMovieQueriesUseCaseMock()),
didSelect: didSelect
)
// when
viewModel.didSelect(item: MoviesQueryListItemViewModel(query: selectedQueryItem.query))
// then
XCTAssertEqual(actionMovieQuery, selectedQueryItem)
XCTAssertEqual(delegateNotifiedCount, 1)
}
}
extension DefaultMoviesQueryListViewModel {
static func make(
numberOfQueriesToShow: Int,
fetchRecentMovieQueriesUseCaseFactory: @escaping FetchRecentMovieQueriesUseCaseFactory,
didSelect: MoviesQueryListViewModelDidSelectAction? = nil
) -> DefaultMoviesQueryListViewModel {
DefaultMoviesQueryListViewModel(
numberOfQueriesToShow: numberOfQueriesToShow,
fetchRecentMovieQueriesUseCaseFactory: fetchRecentMovieQueriesUseCaseFactory,
didSelect: didSelect,
mainQueue: DispatchQueueTypeMock()
)
}
}