-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from f-lab-edu/feature/FixInputOutput
FetchRecipeDetailUseCaseTests를 생성하였습니다
- Loading branch information
Showing
3 changed files
with
258 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
HomeCafeRecipes/HomeCafeRecipesTests/FetchRecipeDetailUseCaseTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// | ||
// FetchRecipeDetailUseCaseTests.swift | ||
// HomeCafeRecipesTests | ||
// | ||
// Created by 김건호 on 7/17/24. | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
|
||
import RxSwift | ||
|
||
@testable | ||
import HomeCafeRecipes | ||
|
||
final class FetchRecipeDetailUseCaseTests: XCTestCase { | ||
|
||
var fetchRecipeDetailRepository: FetchRecipeRepositoryMock! | ||
var disposeBag: DisposeBag! | ||
|
||
final class FetchRecipeRepositoryMock: RecipeDetailRepository { | ||
var fetchRecipeDetailCallCount: Int = 0 | ||
var fetchRecipeDetailStub: Single<Recipe> = .just(Recipe.dummyRecipe()) | ||
func fetchRecipeDetail(recipeID: Int) -> Single<Recipe> { | ||
fetchRecipeDetailCallCount += 1 | ||
return fetchRecipeDetailStub | ||
} | ||
} | ||
|
||
func createUseCase() -> FetchRecipeDetailUseCase { | ||
let usecase = FetchRecipeDetailUseCaseImpl( | ||
repository: fetchRecipeDetailRepository | ||
) | ||
return usecase | ||
} | ||
|
||
override func setUpWithError() throws { | ||
fetchRecipeDetailRepository = .init() | ||
disposeBag = .init() | ||
} | ||
} | ||
|
||
extension FetchRecipeDetailUseCaseTests { | ||
|
||
func test_execute를_호출하면_RecipeDetailRepository의_fetchRecipeDetail을_호출합니다(){ | ||
|
||
// Given | ||
|
||
let usecase = createUseCase() | ||
fetchRecipeDetailRepository.fetchRecipeDetailStub = .just(Recipe.dummyRecipe()) | ||
|
||
// When | ||
|
||
usecase.execute(recipeID: 1) | ||
.subscribe() | ||
.disposed(by: disposeBag) | ||
|
||
// Then | ||
|
||
XCTAssertEqual(fetchRecipeDetailRepository.fetchRecipeDetailCallCount, 1) | ||
} | ||
|
||
func test_RecipeDetailRepository의_성공응답이오면_Recipe를_반환합니다(){ | ||
|
||
// Given | ||
|
||
let usecase = createUseCase() | ||
let recipe = Recipe.dummyRecipe() | ||
fetchRecipeDetailRepository.fetchRecipeDetailStub = .just(recipe) | ||
let expectation = self.expectation(description: "Fetch Recipe Success") | ||
|
||
// When | ||
|
||
usecase.execute(recipeID: 1) | ||
.subscribe(onSuccess: { result in | ||
if case .success(let fetchedRecipe) = result { | ||
// Then | ||
|
||
XCTAssertEqual(fetchedRecipe.id, recipe.id) | ||
expectation.fulfill() | ||
} else { | ||
XCTFail("Expected success but got failure") | ||
} | ||
}, onFailure: { error in | ||
XCTFail("Expected success but got error: \(error)") | ||
}) | ||
.disposed(by: disposeBag) | ||
|
||
wait(for: [expectation], timeout: 1.0) | ||
XCTAssertEqual(fetchRecipeDetailRepository.fetchRecipeDetailCallCount, 1) | ||
} | ||
|
||
func test_RecipeDetailRepository의_실패응답이오면_Error를_반환합니다() { | ||
|
||
// Given | ||
|
||
let usecase = createUseCase() | ||
let error = NSError(domain: "TestError", code: -1) | ||
fetchRecipeDetailRepository.fetchRecipeDetailStub = .error(error) | ||
let expectation = self.expectation(description: "Fetch Recipe Failure") | ||
|
||
// When | ||
|
||
usecase.execute(recipeID: 1) | ||
.subscribe(onSuccess: { result in | ||
if case .failure(let receivedError as NSError) = result { | ||
// Then | ||
|
||
XCTAssertEqual(receivedError.domain, error.domain) | ||
XCTAssertEqual(receivedError.code, error.code) | ||
expectation.fulfill() | ||
} else { | ||
XCTFail("Expected failure but got success") | ||
} | ||
}, onFailure: { error in | ||
XCTFail("Expected failure but got error: \(error)") | ||
}) | ||
.disposed(by: disposeBag) | ||
|
||
wait(for: [expectation], timeout: 1.0) | ||
XCTAssertEqual(fetchRecipeDetailRepository.fetchRecipeDetailCallCount, 1) | ||
|
||
} | ||
|
||
} |
111 changes: 111 additions & 0 deletions
111
HomeCafeRecipes/HomeCafeRecipesTests/RecipeDeatilInteractorTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// | ||
// RecipeDeatilInteractorTests.swift | ||
// HomeCafeRecipesTests | ||
// | ||
// Created by 김건호 on 7/9/24. | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
|
||
import RxSwift | ||
|
||
@testable | ||
import HomeCafeRecipes | ||
|
||
final class RecipeDetailInteractorTests: XCTestCase { | ||
var fetchRecipeDetailUsecase: FetchRecipeDetailUseCaseMock! | ||
var delegate: RecipeDetailInteractorDelegateMock! | ||
|
||
final class FetchRecipeDetailUseCaseMock: FetchRecipeDetailUseCase { | ||
var executeCallCount: Int = 0 | ||
var executeStub: Single<Result<Recipe, Error>> = .just(.failure(NSError())) | ||
func execute(recipeID: Int) -> Single<Result<Recipe, Error>> { | ||
executeCallCount += 1 | ||
return executeStub | ||
} | ||
} | ||
|
||
final class RecipeDetailInteractorDelegateMock: RecipeDetailInteractorDelegate { | ||
var fetchedCallCount: Int = 0 | ||
var fetchedRecipeResult: Result<Recipe, Error>? | ||
func fetchedRecipe(result: Result<Recipe, Error>) { | ||
fetchedCallCount += 1 | ||
fetchedRecipeResult = result | ||
} | ||
} | ||
|
||
func createInteractor(recipeID: Int = 0) -> RecipeDetailInteractor { | ||
let interactor = RecipeDetailInteractorImpl( | ||
fetchRecipeDetailUseCase: fetchRecipeDetailUsecase, | ||
recipeID: recipeID | ||
) | ||
|
||
interactor.delegate = delegate | ||
return interactor | ||
} | ||
|
||
override func setUpWithError() throws { | ||
fetchRecipeDetailUsecase = .init() | ||
delegate = .init() | ||
} | ||
} | ||
|
||
// MARK: viewDidLoad | ||
|
||
extension RecipeDetailInteractorTests { | ||
|
||
func test_화면이_로드될때_FetchRecipeDetailUsecase를_호출합니다() { | ||
// given | ||
let interactor = createInteractor() | ||
|
||
// when | ||
interactor.viewDidLoad() | ||
|
||
// then | ||
XCTAssertEqual(self.fetchRecipeDetailUsecase.executeCallCount, 1) | ||
} | ||
|
||
func test_FetchRecipeDetailUsecase의_성공응답이오면_Delegate로_성공을_전달합니다() { | ||
// given | ||
let interactor = createInteractor() | ||
let recipe = Recipe.dummyRecipe() | ||
fetchRecipeDetailUsecase.executeStub = .just(.success(recipe)) | ||
|
||
// when | ||
interactor.viewDidLoad() | ||
|
||
// then | ||
XCTAssertEqual(self.fetchRecipeDetailUsecase.executeCallCount, 1) | ||
XCTAssertEqual(self.delegate.fetchedCallCount, 1) | ||
|
||
if case .success(let fetchedRecipe)? = delegate.fetchedRecipeResult { | ||
XCTAssertEqual(fetchedRecipe.id, recipe.id) | ||
} else { | ||
XCTFail("Expected success but got failure or nil") | ||
} | ||
} | ||
|
||
func test_FetchRecipeDetailUsecase의_실패응답이오면_Delegate로_실패를_전달합니다() { | ||
|
||
// given | ||
let interactor = createInteractor() | ||
let error = NSError(domain: "TestError", code: -1) | ||
fetchRecipeDetailUsecase.executeStub = .just(.failure(error)) | ||
|
||
// when | ||
interactor.viewDidLoad() | ||
|
||
// then | ||
XCTAssertEqual(self.fetchRecipeDetailUsecase.executeCallCount, 1) | ||
XCTAssertEqual(self.delegate.fetchedCallCount, 1) | ||
|
||
if case .failure(let fetchedError as NSError) = delegate.fetchedRecipeResult { | ||
XCTAssertEqual(fetchedError.domain, error.domain) | ||
XCTAssertEqual(fetchedError.code, error.code) | ||
} else { | ||
XCTFail("Expected success but got failure or nil") | ||
} | ||
|
||
} | ||
} |