Skip to content

Commit 47fe88d

Browse files
committed
Add tests for memory leaks for list view model
1 parent 83a9ed3 commit 47fe88d

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

ExampleMVVMTests/Presentation/MoviesScene/MoviesListViewModelTests.swift

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class MoviesListViewModelTests: XCTestCase {
1616
}()
1717

1818
class SearchMoviesUseCaseMock: SearchMoviesUseCase {
19-
var callCount: Int = 0
19+
var executeCallCount: Int = 0
2020

2121
typealias ExecuteBlock = (
2222
SearchMoviesUseCaseRequestValue,
@@ -33,7 +33,7 @@ class MoviesListViewModelTests: XCTestCase {
3333
cached: @escaping (MoviesPage) -> Void,
3434
completion: @escaping (Result<MoviesPage, Error>) -> Void
3535
) -> Cancellable? {
36-
callCount += 1
36+
executeCallCount += 1
3737
_execute(requestValue, cached, completion)
3838
return nil
3939
}
@@ -58,7 +58,8 @@ class MoviesListViewModelTests: XCTestCase {
5858
XCTAssertEqual(viewModel.currentPage, 1)
5959
XCTAssertFalse(viewModel.hasMorePages)
6060
XCTAssertTrue(viewModel.items.value.isEmpty)
61-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
61+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
62+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
6263
}
6364

6465
func test_whenSearchMoviesUseCaseRetrievesFirstPage_thenViewModelContainsOnlyFirstPage() {
@@ -83,7 +84,8 @@ class MoviesListViewModelTests: XCTestCase {
8384
XCTAssertEqual(viewModel.items.value, expectedItems)
8485
XCTAssertEqual(viewModel.currentPage, 1)
8586
XCTAssertTrue(viewModel.hasMorePages)
86-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
87+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
88+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
8789
}
8890

8991
func test_whenSearchMoviesUseCaseRetrievesFirstAndSecondPage_thenViewModelContainsTwoPages() {
@@ -99,7 +101,7 @@ class MoviesListViewModelTests: XCTestCase {
99101
)
100102
// when
101103
viewModel.didSearch(query: "query")
102-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
104+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
103105

104106
searchMoviesUseCaseMock._execute = { requestValue, _, completion in
105107
XCTAssertEqual(requestValue.page, 2)
@@ -115,7 +117,8 @@ class MoviesListViewModelTests: XCTestCase {
115117
XCTAssertEqual(viewModel.items.value, expectedItems)
116118
XCTAssertEqual(viewModel.currentPage, 2)
117119
XCTAssertFalse(viewModel.hasMorePages)
118-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 2)
120+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 2)
121+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
119122
}
120123

121124
func test_whenSearchMoviesUseCaseReturnsError_thenViewModelContainsError() {
@@ -135,7 +138,8 @@ class MoviesListViewModelTests: XCTestCase {
135138
// then
136139
XCTAssertNotNil(viewModel.error)
137140
XCTAssertTrue(viewModel.items.value.isEmpty)
138-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
141+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
142+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
139143
}
140144

141145
func test_whenLastPage_thenHasNoPageIsTrue() {
@@ -150,7 +154,7 @@ class MoviesListViewModelTests: XCTestCase {
150154
)
151155
// when
152156
viewModel.didSearch(query: "query")
153-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
157+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
154158

155159
searchMoviesUseCaseMock._execute = { requestValue, _, completion in
156160
XCTAssertEqual(requestValue.page, 2)
@@ -162,7 +166,8 @@ class MoviesListViewModelTests: XCTestCase {
162166
// then
163167
XCTAssertEqual(viewModel.currentPage, 2)
164168
XCTAssertFalse(viewModel.hasMorePages)
165-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 2)
169+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 2)
170+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
166171
}
167172

168173
func test_whenSearchMoviesUseCaseReturnsCachedData_thenViewModelShowsFirstCachedDataAndAfterFreshData() {
@@ -179,7 +184,8 @@ class MoviesListViewModelTests: XCTestCase {
179184
mainQueue: DispatchQueueTypeMock()
180185
)
181186

182-
let testItemsBeforeFreshData = {
187+
let testItemsBeforeFreshData = { [weak viewModel] in
188+
guard let viewModel else { return }
183189
let expectedItems = cachedPage
184190
.movies
185191
.map { MoviesListItemViewModel(movie: $0) }
@@ -204,7 +210,8 @@ class MoviesListViewModelTests: XCTestCase {
204210
XCTAssertEqual(viewModel.items.value, expectedItems)
205211
XCTAssertEqual(viewModel.currentPage, 1)
206212
XCTAssertTrue(viewModel.hasMorePages)
207-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
213+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
214+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
208215
}
209216

210217
func test_whenSearchMoviesUseCaseReturnsError_thenViewModelShowsCachedData() {
@@ -237,7 +244,8 @@ class MoviesListViewModelTests: XCTestCase {
237244
XCTAssertEqual(viewModel.items.value, expectedItems)
238245
XCTAssertEqual(viewModel.currentPage, 1)
239246
XCTAssertTrue(viewModel.hasMorePages)
240-
XCTAssertEqual(searchMoviesUseCaseMock.callCount, 1)
247+
XCTAssertEqual(searchMoviesUseCaseMock.executeCallCount, 1)
248+
addTeardownBlock { [weak viewModel] in XCTAssertNil(viewModel) }
241249
}
242250

243251
}

0 commit comments

Comments
 (0)