swsnu / swppfall2019

31 stars 23 forks source link

HW2 mocking method #102

Open lllY2Klll opened 4 years ago

lllY2Klll commented 4 years ago

항상 고생하십니다! testing에 대한 practice session ppt를 읽어봤습니다. simulating user behavior 부분에서 버튼을 클릭 했을때 테스팅하는 컴포넌트의 props로 전달받은 clickDone 메소드를 mocking하는 방법은 이해를 했는데 혹시 클릭했을때 실행되어야하는 메소드가 props로 전달받은것이 아니라 테스팅하는 컴포넌트(functional component입니다) 안에 정의되어있을때는 그 메소드가 호출되었는지 확인할 수 있는 방법이 있나요?

kyunggeunlee commented 4 years ago

테스트하고자 하는 컴포넌트 내부에 정의된 함수인 경우 몇번 불렸는지만 체크하기보다는 그 함수가 올바른 결과를 산출하는지를 테스트하는 것이 더 중요합니다.

kyunggeunlee commented 4 years ago

정정하겠습니다. 제가 위 답변에서 잘못된 예제코드를 드렸었습니다. (혼란을 피하기 위해 기존의 답변에서 잘못된 내용을 삭제했습니다)

어떤 클래스의 특정한 함수 하나만을 mocking하려면 prototype을 사용할 수 있습니다.

TodoList.WrappedComponent.prototype.f = jest.fn(...);

하지만 이렇게 하려면, f라는 함수 정의를 반드시 다음과 같이 해야 합니다.

class TodoList extends Component{
    //...
    f() {
        console.log(this);
    }
    //...
    render() {
        f();                                 // this prints "TodoList" instance
        return (<Todo clickDone={this.f}>)   // this prints "Todo" instance
    }
}

그렇지 않고 f = () => {...} 또는 f = function() {...} 를 사용해 f를 정의하면 이 방법을 쓸 수 없습니다.

한가지 주의할 점은, 위와 같은 방식으로 함수를 정의할 경우 this의 바인딩이 달라진다는 것입니다. 예를 들어 위 예제코드에서, f라는 함수가 TodoList 내부에서 호출될 때에는 TodoList 인스턴스를 출력해 주지만, f라는 함수를 Todo의 props로 넘겨주고 Todo에서 f가 호출되는 경우에는 this가 가리키는 대상이 TodoList가 아닌 Todo로 바뀌게 됩니다. 따라서 Todo 내부에서 f가 호출된다면 Todo 인스턴스를 출력합니다.