From 7e653b940c1ae77b07a0e0125a4ee0c4990765f5 Mon Sep 17 00:00:00 2001 From: Bliss Pisit Wetcha <pisit@nimblehq.co> Date: Wed, 4 Oct 2023 18:04:41 +0700 Subject: [PATCH] [#508] Add network test --- Tuist/Interfaces/SwiftUI/Project/Podfile | 1 + Tuist/Interfaces/UIKit/Project/Podfile | 1 + {PROJECT_NAME}Tests/Sources/Dummy/.gitkeep | 0 .../Sources/Dummy/DummyNetworkModel.swift | 14 ++++ .../Dummy/DummyRequestConfiguration.swift | 29 +++++++++ .../Data/NetworkAPI/NetworkAPISpec.swift | 64 +++++++++++++++++++ .../Sources/Utilities/.gitkeep | 0 .../Sources/Utilities/NetworkStubber.swift | 32 ++++++++++ 8 files changed, 141 insertions(+) delete mode 100644 {PROJECT_NAME}Tests/Sources/Dummy/.gitkeep create mode 100644 {PROJECT_NAME}Tests/Sources/Dummy/DummyNetworkModel.swift create mode 100644 {PROJECT_NAME}Tests/Sources/Dummy/DummyRequestConfiguration.swift create mode 100644 {PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift delete mode 100644 {PROJECT_NAME}Tests/Sources/Utilities/.gitkeep create mode 100644 {PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift diff --git a/Tuist/Interfaces/SwiftUI/Project/Podfile b/Tuist/Interfaces/SwiftUI/Project/Podfile index 6dbc2e01..7a0d2eed 100644 --- a/Tuist/Interfaces/SwiftUI/Project/Podfile +++ b/Tuist/Interfaces/SwiftUI/Project/Podfile @@ -7,6 +7,7 @@ def testing_pods pod 'Nimble', '~> 11.0' pod 'Sourcery' pod 'SwiftFormat/CLI' + pod 'OHHTTPStubs/Swift', :configurations => ['Debug Staging', 'Debug Production'] end target '{PROJECT_NAME}' do diff --git a/Tuist/Interfaces/UIKit/Project/Podfile b/Tuist/Interfaces/UIKit/Project/Podfile index cf4fbd43..d5bdbf53 100644 --- a/Tuist/Interfaces/UIKit/Project/Podfile +++ b/Tuist/Interfaces/UIKit/Project/Podfile @@ -7,6 +7,7 @@ def testing_pods pod 'Nimble' pod 'Sourcery' pod 'SwiftFormat/CLI' + pod 'OHHTTPStubs/Swift', :configurations => ['Debug Staging', 'Debug Production'] end target '{PROJECT_NAME}' do diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/.gitkeep b/{PROJECT_NAME}Tests/Sources/Dummy/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/DummyNetworkModel.swift b/{PROJECT_NAME}Tests/Sources/Dummy/DummyNetworkModel.swift new file mode 100644 index 00000000..e6dfb70c --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Dummy/DummyNetworkModel.swift @@ -0,0 +1,14 @@ +// +// DummyNetworkModel.swift +// + +import Foundation + +struct DummyNetworkModel: Decodable { + + static let json = + """ + {"message": "Hello"} + """ + let message: String +} diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/DummyRequestConfiguration.swift b/{PROJECT_NAME}Tests/Sources/Dummy/DummyRequestConfiguration.swift new file mode 100644 index 00000000..1359b72b --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Dummy/DummyRequestConfiguration.swift @@ -0,0 +1,29 @@ +// +// DummyRequestConfiguration.swift +// + +import Alamofire + +@testable import {PROJECT_NAME} + +struct DummyRequestConfiguration: RequestConfiguration { + + var baseURL: String { "https://example.com" } + + var endpoint: String { "" } + + var method: Alamofire.HTTPMethod { .get } + + var encoding: Alamofire.ParameterEncoding { URLEncoding.queryString } +} + +extension DummyRequestConfiguration: RequestConfigurationStubable { + + var sampleData: Data { + DummyNetworkModel.json.data(using: .utf8) ?? Data() + } + + var path: String { + (try? url.asURL().path).string + } +} diff --git a/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift b/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift new file mode 100644 index 00000000..c26bbdd0 --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift @@ -0,0 +1,64 @@ +// +// NetworkAPISpec.swift +// + +import Nimble +import Quick + +@testable import {PROJECT_NAME} + +final class NetworkAPISpec: QuickSpec { + + override func spec() { + + describe("a NetworkAPI") { + + var networkAPI: NetworkAPI! + var requestConfiguration: DummyRequestConfiguration! + + describe("its performRequest") { + + beforeEach { + requestConfiguration = DummyRequestConfiguration() + } + + afterEach { + NetworkStubber.removeAllStubs() + } + + context("when network returns value") { + + beforeEach { + NetworkStubber.stub(requestConfiguration) + networkAPI = NetworkAPI() + } + + it("returns message as Hello") { + let response = try await networkAPI.performRequest( + requestConfiguration, + for: DummyNetworkModel.self + ) + expect(response.message) == "Hello" + } + } + + context("when network returns error") { + + beforeEach { + NetworkStubber.stub(requestConfiguration, data: Data(), statusCode: 400) + networkAPI = NetworkAPI() + } + + it("throws error") { + await expect { + try await networkAPI.performRequest( + requestConfiguration, + for: DummyNetworkModel.self + ) + }.to(throwError()) + } + } + } + } + } +} diff --git a/{PROJECT_NAME}Tests/Sources/Utilities/.gitkeep b/{PROJECT_NAME}Tests/Sources/Utilities/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift b/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift new file mode 100644 index 00000000..85ccb721 --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift @@ -0,0 +1,32 @@ +// +// NetworkStubber.swift +// + +import OHHTTPStubs + +protocol RequestConfigurationStubable { + + var sampleData: Data { get } + var path: String { get } +} + +enum NetworkStubber { + + static func removeAllStubs() { + HTTPStubs.removeAllStubs() + } + + static func stub( + _ request: RequestConfigurationStubable, + data: Data? = nil, + statusCode: Int32 = 200 + ) { + OHHTTPStubs.stub(condition: isPath(request.path)) { _ in + HTTPStubsResponse( + data: data ?? request.sampleData, + statusCode: statusCode, + headers: nil + ) + } + } +}