Jest.mock 클래스 함수와 클래스 변수의 이름이 같을 경우 둘 다 사용하는 방법?

react-native-firebase(이하 RNFirebase)를 쓰고 있는데요. unit test를 도입하려고, yarn test 로 시작해봤습니다. 하지만, RNFirebase에서 딱 걸리네요. 찾아보니, mock을 만들어줘서 넘어가라고 되어 있습니다.

mock option1
처럼 만들거나

아예 텅빈 mock을 다음과 같이 만들어서 쓰라는 조언입니다.
mock option 2

저는 아래 조언을 따라서 다음과 같이 구성했습니다.

그래서 조금 더 테스트가 진행되더군요. 하지만, firebase.firestore.FieldValue.serverTimestamp()를 mock으로 만드는데 어려움이 있습니다. 왜냐하면, 이미 firestore를 함수로 할당해버려서 firebase.firestore() 가 되버렸다는 거지요.

설명이 충분한지 모르겠지만, static method(class method)를 mock만드려면 어떻게 접근하시는 지 궁금합니다.

혹시

firebase.firestore.FieldValue.serverTimestamp()

이 필요할 때 firestore를 다시 할당해주면 되지 않을까요?

1 Like

mock_ 안에 넣어서 mockClass를 넣어 두면 자동으로 mock object가 만들어지는 형태라서, 필요한 시점에 다시 할당하는 게 가능한지 모르겠네요. jest.mock 문법이 익숙하지 않아 그런걸까요?

1 Like

음 방법은 여러 가지가 있는 것 같습니다만 어쨌든 mock을 만든 다음에라도 테스트 중에 수정할 수 있을 것 같습니다~

아래에 예시를 만들어봤습니다:

아래 공식 문서 내용 다시 한 번 살펴 보셔도 좋을 것 같습니다 (문서가 많이 보강됐네요!)

2 Likes

위 선기님 코드 링크가 안되네요. 한번 봐주시겠어요? 감사합니다. :slight_smile:

1 Like

네 링크 수정했습니다~ ~~~~~~~

2 Likes

제시해주신 샘플 프로젝트 경우에는 firebase를 사용하고 있는데요. 제 프로젝트에서는 RNFirebase 를 쓰고 있습니다. 네이티브 코드를 한번더 wrapping한 라이브러리에요. 그래서인지 좀 어렵네요. ^^;;

1 Like

여기 저랑 같은 문제를 다른 표현으로 한 게 있습니다. 아직 답변이 안달렸는데 이 케이스에 대한 jest 문서는 안보이는 거 같군요. ㅠㅠ

1 Like

이게 도움이 될지 모르겠군요. Jest mock 객체는 호출 순서에 따라 반환결과를 달리하도록 모킹할 수 있습니다.

1 Like

답변 감사합니다.

하지만 제가 갖고 있는 문제는 firebase.firestore.FieldValue.ServerTimestamp()firebase.firestore() 이 두가지를 함께 mocking하는 방법을 모르겠다는 점이에요.

즉, https://gist.github.com/choipd/f7d85619107d58a191dacff8a85b4ad0
이 코드에서 123번 줄과 같이 firebase의 static function으로 firebase.firestore()을 정의 해버리면, firebase의 static member variable로 firebase.firestore를 정의 할 수 없게 된다는 문제에요.

이 경우 말씀하신 호출 순서에 따라 반환결과를 다르게 하는 것으로 해결될 수 있을까요?

아하. 제가 질문의도 파악을 잘못했군요. 죄송합니다 :sweat:

이 경우는 static 메서드니까 그냥 firebase.firestore 접근해서 직접 프로퍼티 넣어주시면 되지 않나요?

class RNFirebase
  static firestore () {
    if(!this.firestoreInstance) {
      this.firestoreInstance = new Firestore()
    }
    return this.firestoreInstance
  }
}

RNFirebase.firestore.FieldValue = {
  ServerTimestamp: jest.fn()
}

export default RNFirebase
3 Likes

그렇게 써주니, 넘어가네요. ^^ 간단히 해결되는 거였는데 몇일 계속 보고 있었네요.
정말 감사합니다. :slight_smile:

1 Like

클래스래봐야 나오는건 결국 자바스크립트 오브젝트니까요 ㅎㅎ

static firestore = (() => { ... })() 이렇게 클래스 안쪽에 초기화 코드를 넣을 수도 있겠습니다.

3 Likes