[TDD] AuthManager When Sign-in Service Is Not Decided

Muhammad Alfiansyah
2 min readFeb 6, 2025

Instead of writing logic directly inside AuthManager, we abstract it using AuthServiceProtocol.

protocol AuthServiceProtocol {
func signIn(completion: @escaping (Bool) -> Void)
func signOut()
}

class AuthManager {
private let authService: AuthServiceProtocol

init(authService: AuthServiceProtocol) {
self.authService = authService
}

func signIn(callback: @escaping (Bool) -> Void) {
authService.signIn { success in
callback(success)
}
}

func signOut() {
authService.signOut()
}
}
  • AuthManager now works independently of Google/Facebook.
  • We can inject a mock service for testing.
  • The real sign-in logic can be implemented later.

Since we don’t have Google/Facebook auth yet, we create a mock service that simulates login/logout behavior.

class MockAuthService: AuthServiceProtocol {
var isSignInSuccessful = true

func signIn(completion: @escaping (Bool) -> Void) {
completion(isSignInSuccessful) // Simulates login result
}

func signOut() {
print("User signed out")
}
}
  • We avoid calling real authentication APIs in tests.
  • We can control the sign-in success/failure behavior.

Now, we can test AuthManager using XCTest.

import XCTest

class AuthManagerTests: XCTestCase {
var authManager: AuthManager!
var mockAuthService: MockAuthService!

override func setUp() {
super.setUp()
mockAuthService = MockAuthService()
authManager = AuthManager(authService: mockAuthService)
}

func testSignInSuccess() {
mockAuthService.isSignInSuccessful = true
let expectation = self.expectation(description: "Sign-in should succeed")

authManager.signIn { success in
XCTAssertTrue(success, "Expected sign-in to be successful")
expectation.fulfill()
}

wait(for: [expectation], timeout: 1.0)
}

func testSignInFailure() {
mockAuthService.isSignInSuccessful = false
let expectation = self.expectation(description: "Sign-in should fail")

authManager.signIn { success in
XCTAssertFalse(success, "Expected sign-in to fail")
expectation.fulfill()
}

wait(for: [expectation], timeout: 1.0)
}

func testSignOut() {
// No need for an async expectation since signOut() is synchronous
authManager.signOut()
XCTAssert(true, "Sign-out function executed successfully")
}
}
  • testSignInSuccess → Simulates a successful login.
  • testSignInFailure → Simulates a failed login.
  • testSignOut → Ensures signOut() runs without errors.

--

--

No responses yet