Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

길고 지저분하고 제대로 테스트되지 않은 컨트롤러를 리팩토링하는 방법

Rails 경력의 어느 시점에서, 당신은 프로그래밍을 영원히 포기하고 싶게 만드는 컨트롤러와 마주치게 될 것입니다. 전체 기능에 대한 모든 코드 줄을 포함할 수 있습니다. 15개의 before_filters가 있을 수 있습니다. 모두 인스턴스 변수를 통해 통신하고 특정 순서로 호출되어야 하며 그렇지 않으면 일이 터집니다. 그리고 불가피하게 테스트는 다음과 같을 것입니다.

test "index" do
  get :index
  assert_response :success
end

대박. 100% 테스트 커버리지, 맞죠?

눈을 감고 존재하지 않는 척하는 것이 좋지만 언젠가는 이러한 컨트롤러 중 하나에서 버그를 수정해야 합니다. 그리고 훌륭한 소프트웨어 개발자가 된다면 발견한 것보다 더 나은 코드를 남기고 싶을 것입니다.

그러나 특히 신뢰할 만한 좋은 테스트 없이 어떻게 리팩토링할 수 있습니까?

테스트 받기(어떻게든)

리팩토링하는 동안 안전하다고 느끼려면 좋은 테스트가 필요하지만 작성할 수는 없습니다. 까지 이 코드에 대한 좋은 테스트 당신은 리팩토링. 그래서 당신은 무엇을 할 수 있습니까?

글쎄, 당신의 컨트롤러가 얼마나 잘못 작성되었든, 당신은 여전히 ​​일부 데이터를 컨트롤러에 보내고 그로부터 어떤 응답을 기대하는 통합 테스트를 작성할 수 있습니다. 지금은 컨트롤러가 존재하는지 확인하는 테스트를 작성해야 합니다. 행동은 변경되지 않습니다. 리팩토링하면 됩니다.

이러한 테스트는 단위 테스트만큼 집중되지 않습니다. 그러나 이러한 높은 수준의 테스트를 통해 수행하려는 리팩토링이 모든 것을 중단시키지는 않을 것이라고 안심할 수 있습니다. 그리고 코드를 작성하는 과정은 코드를 더 잘 이해하는 데 도움이 되며 리팩토링 방법을 결정하는 데 도움이 됩니다.

종속성 해제

나쁜 컨트롤러 코드가 나쁜 이유는 무엇입니까? 대부분의 경우 암시적 종속성 before_filters 사이 , 도우미 메서드 또는 200줄 함수의 다른 부분. 너무 일찍 리팩토링한 경우일 수도 있습니다. 코드를 더 좋게 만들려면 이러한 종속성을 깨야 합니다.

Rails 컨트롤러의 경우 종속성을 깨는 쉬운 방법이 있습니다. before_filters에서 코드를 복사하기만 하면 됩니다. , 도우미 메서드, 수퍼 클래스 및 컨트롤러-ish 코드가 숨길 수 있는 다른 모든 곳. 그런 다음 해당 메서드에 대한 호출을 복사한 코드로 바꿉니다.

나중에 코드를 더 이해하기 쉬운 방식으로 리팩토링할 수 있도록 일시적으로 코드 건조를 취소합니다. 보기 흉하지만 이제 모든 코드가 공개되었습니다. 어떤 부분이 상호 작용하고 모든 것이 어떻게 흐르는지 볼 수 있어야 합니다.

(이 과정에서 인라인으로 인해 손상되지 않는지 확인하기 위해 모든 변경 후에 테스트를 실행해야 합니다.)

테스트 가능한 코드로 리팩터링

이제 코드를 리팩토링할 준비가 되었습니다. 기본 추출 방법을 고수할 것입니다. , 객체 추출 , 풀업 방식 -유형 리팩토링. 몇 가지 다른 방법으로 코드를 리팩토링하고 어떤 것이 가장 좋은지 확인하세요.

처음 몇 단계 동안에는 높은 수준의 통합 테스트를 안전망으로 사용할 수 있습니다. 하지만 곧 더 나은 것을 원하게 될 것입니다.

리팩토링하면서 코드를 테스트하기 쉽게 만들 수 있는 기회를 찾으세요. 이것은 일반적으로 테스트 더블을 주입할 장소를 만들고, 개체 간의 종속성을 줄이고, 컨트롤러가 쉽게 만들고 단위 테스트할 수 있는 개체에 의존하게 만드는 것을 의미합니다. 코드를 테스트 가능한 개체로 이동하면 컨트롤러가 작아지고 이해하기 쉬우며 자체 테스트가 더 쉬워집니다.

번호 목록 형식으로 받을 수 있나요?

다시 한 번, 다음은 대형 컨트롤러를 분해하는 단계입니다.

  1. 컨트롤러에 대해 높은 수준의 통합 테스트를 실행합니다.
  2. 테스트를 실행하고 통과하는지 확인하세요.
  3. 인라인 before_filters , 슈퍼클래스 메서드 및 코드를 숨기는 기타 추상화.
  4. 테스트를 실행하고 여전히 통과하는지 확인합니다.
  5. 리팩토링 수행(추출 방법 , 서비스 객체 추출 , 인스턴스 변수를 로컬로 교체 , 등.). 코드가 더 나은지 확인하세요.
  6. 테스트를 실행하고 여전히 통과하는지 확인합니다.
  7. 코드를 방금 추출했다면 추출한 개체 또는 메서드에 대해 몇 가지 단위 테스트를 작성하세요.
  8. 테스트를 실행하고 여전히 통과하는지 확인합니다.
  9. 컨트롤러에 여전히 작업이 필요한 경우 5단계로 돌아갑니다.

다음은 무엇입니까?

더 자세히 알고 싶다면 레거시 코드로 효과적으로 작업하기는 테스트 없이 유지 관리할 수 없는 코드를 사용하여 작업할 수 있는 것으로 바꾸는 성경입니다. 강력 추천합니다 , 거대한 모놀리식 컨트롤러를 자주 마주하게 된다면(그리고 리팩토링이 나만큼 재미있다면).

이제 당신의 공포 이야기를 들어보시죠! 당신이 작업한 최악의 컨트롤러 코드는 어떻게 생겼나요?