TIL27 ✨

YaR Lab·2023년 5월 29일
0

TIL✨

목록 보기
17/135
post-thumbnail

23.05.30

비동기 메서드 테스트

  • 작업을 동기적으로 실행하지 않고, 별도의 스레드 또는 작업 큐에서 비동기적으로 실행되는 메서드
  • 메인 스레드에서 블로킹되지 않고 비동기적으로 작업을 수행
  • 사용자 경험을 향상시킬 수 있음
  • 비동기 작업은 보통 백그라운드 스레드에서 실행
  • 비동기 메서드는 비동기적으로 실행되기 때문에 호출하는 즉시 결과를 반환하지 않고, 작업이 완료된 이후에 클로저를 통해 결과를 처리함

expectation(description:)

어떤 것이 수행되어야 하는지를 description으로 정해줍니다.

여러 개의 expectation을 만들어서 작업을 기다려줄 수도 있습니다.

fulfill()

정의해둔 expectation이 충족되는 시점에 호출하여 동작을 수행했음을 알립니다.

wait(for:timeout:)

expectation을 배열로 담아 전달하여 배열 속의 expectation이 모두 fulfill 될 때까지 기다립니다. timeout을 설정하여 시간을 제한할 수 있습니다.

timeout

비동기 작업을 기다리는 제한시간
TimeInterval(Double) 값을 전달받음

URLSession

URLSession -> datatask -> URLSessionDataTask -> resume -> Networking -> completionHandler

테스트 더블

테스트를 진행하기 어려운 경우 이를 대신하여 테스트를 진행할 수 있도록 만들어 주는 객체
테스트를 진행하는 동안 실제 객체를 잠깐 바꿔치기해서 테스트 진행
테스트 대상 코드 격리
테스트 속도 개선
예측 불가능한 실행 요소 제거
특수 상황 시뮬레이션
감춰진 정보를 얻어냄

Dummy(모조의, 가짜의)

가장 기본적 TestDouble
어떤 기능이 구현 되어 있지 않은 인스턴스화된 객체로 사용
Dummy의 메서드는 정상적으로 동작하지 않음

Stub (쓰다 남은 물건의 토막, 남은 부분)

Dummy가 실제로 동작하는 것처럼 만들어 실제 코드를 대신해서 동작해 주는 객체
테스트가 곤란한 부분의 객체를 도려내어 그 역할을 최소한으로 구현
상태 기반 테스트(State Base Test) - 메서드를 호출하고 결괏값과 예상값을 비교하는 테스트

Fake

Stub보다 구체적으로 동작
실제 앱의 동작에서는 적합하지 않은 객체
실제 앱의 코드와 비슷하지만 그 동작을 단순화하여 구현한 객체

spy

Stub의 역활을 가지면서 호출된 내용에 대한 방법, 과정, 약간의 정보를 기록하는 객체
호출됐는지, 몇 번 호출됐는지 등에 대한 정보를 기록

Mock

실제 객체와 가장 비슷하게 구현된 수준의 객체
행위 기반 테스트(Behavior Base Test) - 행위의 시나리오를 만들어 놓고, 시나리오대로 동작했는지 확인

의존성 주입(Dependency Injection)

하나의 객체가 다른 객체의 의존성을 제공하는 기술
객체간의 결합도를 낮추기 위해서 사용

의존성: 어떤 객체가 내부에서 생성하여 가지고 있는 객체

class Car {
    var wheel: Wheel = Wheel()
}

class Wheel {
    var weight = 10
}

Car클래스는 Wheel클래스에 의존하고 있다

class Car {
    var wheel: Wheel

    init(wheel: Wheel) {
        self.wheel = wheel
    }
}

class Wheel {
    var weight = 10
}

let myWheel = Wheel()
let myCar = Car(wheel: myWheel)

외부에서 객체를 생성하여 내부에 주입시켜주는 행위(의존성 주입)

TDD

테스트를 작성하면서 코드를 완성시켜나가는 방법론
Timely원칙에 의거
테스트가 불가능한 코드를 작성하는 것을 방지
안전한 코드 작성 가능
의존성이 낮은 코드 작성 가능
개발 속도 현저히 저하됨

Red: 실패하는 테스트 작성
Green: 실패한 테스트를 통과하기 위해 최소한의 변경을 하여 테스트 성공
Refator: 테스트 성공을 유지하면서 코드를 더 나은 방향으로 개선
Red -> Green -> Refator -> Red -> Green

try

키워드 try? try!
에러를 던질수 있는 코드를 알려줌
핸들링을 해줄 수 있는 곳

try? -> nil로 바꿔줌
as? -> nil로 바꿔줌

Linked List

단순 연결 리스트
이중 연결 리스트 양방향 주소
원형 연결 리스트 끝주소가 첫주소를 가지고 있음

Stack

xcode file navigator 파일명 수정

파일명 클릭

Generic

중복을 피하고 코드를 유연하게 작성할때 사용

T(Type Parameter)

실제 함수가 호출될 때 해당 매개변수의 타입으로 대체되는 Placeholder
자리 타입에 불과함
네이밍: 가독성을 위해 T또는 V같은 단일 문자, 혹은 UpperCamelCase

Generic function

func genericTest<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

var a = "h"
var b = "hello"
genericTest(&a, &b)
print(a, b) //hello, h

Generic Type

struct, class, enum에 사용

struct Stack<T> {
    let items: Array<T> = []
    let item: [T] = []
}

let stackTest: Stack<Int> = Stack()

print(stackTest.items)
print(type(of: stackTest.items))

Type Constraints

Protocol Constraints
func isSameValues<T>(_ a: T, _ b: T) -> Bool { //error
    return a == b
}

let a = 2
let b = 3
print(isSameValues(a, b))
func isSameValues<T: Equatable>(_ a: T, _ b: T) -> Bool {
    return a == b
}

let a = 2
let b = 3
print(isSameValues(a, b))

Type prameter에 Equatable프로토콜 제약을 줌

Class Constraints
class PencilCase{ }
class Pen { }
class Pencil: PencilCase{ }

func testClassConstraints<T: PencilCase>(_ pencil: T) {
    print("sucess")
}

let test: Pen = .init()
let test2: Pencil = .init()
let test3: PencilCase = .init()

testClassConstraints(test) //error
testClassConstraints(test2)
testClassConstraints(test3)

클래스, 서브클래스에 대한 PencilCase 제약을 줌

Generic Type extention

extension Array where Element: FixedWidthInteger {
    mutating func pop() -> Element { return self.removeLast() }
}

var integerArray = [1, 2, 3]
var stringArray = ["h", "e", "l", "l", "o"]

print(integerArray.pop())
print(stringArray.pop()) //error: 'String' conform to 'FixedWidthInteger'

기존 type parameter name과 동일한 name을 쓰면 됨
where을 통해 type parameter인 ElementFixedWidthInteger프로토콜을 준수해야 한다고 정의할 수 있음

Generic Function overloading

func genericTest<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

func genericTest(_ a: inout Int, _ b: inout Int) {
    let temp = a
    a = b
    b = temp
}

var a = "h"
var b = "hello"
genericTest(&a, &b)
var a1 = 1
var b2 = 2
genericTest(&a1, &b2)
print(a, b) // hello h
print(a1, b2) // 2 1

타입이 지정된 함수가 제너릭 함수보다 우선순위가 높다

0개의 댓글