내가 만들었고 내가 확인하기 때문에 실수는 눈에 잘 안 띈다.
그래서 내가 과연 정말로 잘 하고 있는가? 에 대한 질문은 언제나 고통스럽다.
분명 잘 안된 부분이 있을 텐데 그게 내 눈에 띄지 않으니까.
그래서 언제나 내가 뭔가를 만든 것들을 공유한다는 것에 부담을 가져서, 사실 지금 블로그 글을 쓰는 것도 상당히 두렵기도 하고, 뭐 아무튼 별 이야기는 아니지만 갑자기 그런 기분이 든다.
별 이야기는 아니니 본론으로 넘어가면 오늘은 내가 만드려는 JWK 라이브러리의 encode, fetch 부분의 단위 테스트를 작성할 것이다.
encode와 fetch 부분은 생각보다 작성할 테스트의 양이 적어 한번에 진행하는 것이 좋다고 생각되서 이렇게 구성하였다.
이제 이번에 encode, fetch 기능에 대한 단위테스트를 작성하고 나면 이제 fetcher 기능과 JWK 자체 기능, 그리고 잡다한 것들에 대한 부분만 남는다.
드디어 단위테스트의 고지가 눈에 보이니 힘내서 가 보도록 하겠다.
JWK 에서는 bigint
표현을 빅 엔디안으로 구성된 바이트를 base64로 인코딩해 표현한다.
그런데 실수로 base64 인코딩을 빼먹었다.
치명적이지만 단순하고 찾기 쉬운 에러였다.
JWK에선 주어진 필드 이외에도 수많은 필드가 올 수 있다고 규정하고 있다.
그런데 나는 *jwk.UnknownKey
라는 이해 할 수 없는 kty
에 대해서 사용되는 별도의 데이터가 존재함과 동시에 AllowUnknownField
라는 설정값이 존재한다.
이때 jwk.UnknownKey
는 정말로 어떤 필드들이 필요한지 모르므로, 만약 jwk.UnknownKey
를 파싱할 때에는 AllowUnknownField
가 반드시 true
라고 가정하고 파싱해야 했다.
그런데 나는 jwk.UnknownKey
를 파싱할 때 AllowUnknownField
의 값을 무시하지 않는 실수를 했다. 그래서 디코더의 순서와 전반적 코드 배치를 변경해서 해당 문제를 수정했다.
여기저기 코드가 길어서 캡쳐는 생략
디코딩 과정에서 key_ops
필드는 map[KeyOp]struct{}
타입인데 해당 타입이 디코딩 시에는 nil 로 설정되는 특징이 있었다.
만약 이렇게 구현하면, 나중에 사용자가 키에 op를 추가할 때 문제가 될 수 있으므로 해당 필드가 nil이 되지 않도록 수정하였다.
만약 출력할 위치가 nil
이면 에러를 리턴해야 한다.
사실 너무나 당연한건데 깜빡하고 있었다. 인코딩할 대상이 nil이면 에러를 리턴해야지...
해당 기능은 사실상 디코딩 위에 https 리퀘스트만 추가한거다 보니 에러를 찾지 못했다.
단위 테스팅을 수행하며 내 예상보다도 훨씬 더 많은 사소하거나, 혹은 치명적인 에러들을 많이 찾을 수 있었다.
또한 직접 내 라이브러리를 사용하며 개선점이 보이기도 하는 등, 정말 큰 도움이 된 것 같다.
물론 괴롭지만...
그래도 이제 코드 커버리지는 70.8%, 이제 큼직한 커버리지는 golang-jwt 기능과 jwk 자체 메서드들, 그리고 fetcher 기능만 남았다.
사실 해당 부분 모두 합쳐도 decode에는 안 될 것 같으니 계속해서 나가 보도록 하겠다.
그럼 계속해서 화이팅!