Skip to content

Conversation

@LJIN24
Copy link
Collaborator

@LJIN24 LJIN24 commented Nov 6, 2025

##2주차 테스트코드 실습 과제

오늘 있었던 문제

MainViewController에 있던 이메일 / 패스워드 유효성 검사 로직private 메서드여서
테스트 코드에서 직접 접근할 수 없는 문제가 발생 처음에는 그냥 메서드에서 private을 지우고 internal로 변경해줬습니다.
그러나 이건 별로 좋은 방법은 아닌거 같아서 서치를 해봤습니다.

테스트할 함수를 담은 별도의 Validator 객체로 분리 하는 방식이 괜찮아 보였습니다


변경 사항

  • LoginValidator 객체 만들기

  • 기존 MainViewControllerisValidEmail(_:), isValidPassword(_:) 을 Validator로 이동했습니다.

  • MainViewController는 이제 Validator를 통해 검사를 수행하도록 수정했습니다.

    • Validator를 대상으로 하는 단위 테스트를 작성했습니다.
  • 테스트가 불가능했던 private 메서드는 Validator 메서드로 대체했습니다.

class LoginValidator {

  // MARK: - Properties

  private let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
  private let passwordRegex = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]).{8,}$"

  // MARK: - Validation Methods

  func isValidEmail(_ string: String?) -> Bool {
      guard let string = string else { return false }

      return string.range(of: self.emailRegex, options: .regularExpression) != nil
  }

  func isValidPassword(_ string: String?) -> Bool {
      guard let string = string else { return false }

      return string.range(of: self.passwordRegex, options: .regularExpression) != nil
  }
}
//
//  sopt_37th_02SeminarTests.swift
//  sopt-37th-02SeminarTests
//
//  Created by JIN on 11/15/25.
//

import XCTest
@testable import sopt_37th_02Seminar

final class sopt_37th_02SeminarTests: XCTestCase {

  var sut: LoginValidator!

  override func setUpWithError() throws {
      try super.setUpWithError()
      sut = LoginValidator()
  }

  override func tearDownWithError() throws {
      try super.tearDownWithError()
  }

  // MARK: - Login Validation Tests

  func test_isValidEmail_ValidEmailProvided_ReturnsTrue() throws {
      // Given
      let validEmails = [
          "test@example.com",
          "user.name@domain.co.kr",
          "user+tag@example.com",
          "test123@test-domain.com"
      ]

      // When & Then
      for email in validEmails {
          let result = sut.isValidEmail(email)
          XCTAssertTrue(result, "Expected '\(email)' to be valid")
      }
  }

  func test_isValidEmail_InvalidEmailProvided_ReturnsFalse() throws {
      // Given
      let invalidEmails = [
          "notanemail",
          "@example.com",
          "user@",
          "user@domain",
          "",
          nil
      ]

      // When & Then
      for email in invalidEmails {
          let result = sut.isValidEmail(email)
          XCTAssertFalse(result, "Expected '\(email ?? "nil")' to be invalid")
      }
  }

  func test_isValidPassword_ValidPasswordProvided_ReturnsTrue() throws {
      // Given
      let validPasswords = [
          "Test1234!",
          "MyP@ssw0rd",
          "SecurePass123#",
          "Abcd123!@#"
      ]

      // When & Then
      for password in validPasswords {
          let result = sut.isValidPassword(password)
          XCTAssertTrue(result, "Expected '\(password)' to be valid (must contain letters, numbers, special chars, and be 8+ chars)")
      }
  }

  func test_isValidPassword_InvalidPasswordProvided_ReturnsFalse() throws {
      // Given
      let invalidPasswords = [
          "short1!", //8자리 이하
          "NoNumbers!", //숫자없음
          "NoSpecial123", //특수문자없음
          "12345678!", //글자없음
          "",  //빈값
          nil  //nil 값
      ]

      // When & Then
      for password in invalidPasswords {
          let result = sut.isValidPassword(password)
          XCTAssertFalse(result, "Expected '\(password ?? "nil")' to be invalid")
      }
  }
}

@LJIN24 LJIN24 changed the title 2주차 실습과제 추가 [Feat] 테스트코드 2주차 과제 Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants