programing

모키토 사용시verify()?

goodsources 2022. 8. 3. 23:15
반응형

모키토 사용시verify()?

나는 3가지 목적을 위해 jUnit 테스트 케이스를 작성한다.

  1. 코드가 모든(또는 대부분의) 입력 조합/값에서 필요한 모든 기능을 충족하는지 확인합니다.
  2. 구현을 변경할 수 있는지 확인하고 JUnit 테스트 케이스에 의존하여 모든 기능이 아직 만족스럽다는 것을 알 수 있습니다.
  3. 모든 사용 사례에 대한 문서로서 코드를 다시 작성해야 할 경우 리팩터링의 사양으로 기능합니다.(코드를 수정하고 jUnit 테스트가 실패하면 사용 사례를 놓칠 수 있습니다.)

인지 모르겠다Mockito.verify()사용해야 합니다.verify()주지 (따라서 기능에는 영향이 없지만 구현을 변경하면 jUnits가 파손됩니다).

찾고 있는 제품:

  1. 적절한 사용을 위한 가이드라인은 무엇입니까?Mockito.verify()

  2. jUnits가 테스트 대상 클래스의 구현을 인지하거나 밀접하게 연계하는 것이 기본적으로 올바른가?

클래스 A의 계약에 타입 C 객체의 메서드B를 호출하는 사실이 포함되어 있는 경우 타입 C를 모의하여 메서드B가 호출되었음을 검증하여 테스트해야 합니다.

즉, 클래스 A의 계약에는 타입 C(인터페이스 또는 클래스일 수 있음)에 대해 충분히 상세하게 기술되어 있습니다.즉, 단순한 「시스템 요건」을 넘어, 실장을 설명하는 레벨의 사양에 대해 이야기하고 있습니다.

이것은 유닛 테스트에서는 정상입니다.유닛 테스트에서는, 각 유닛이 「올바른 일」을 실시하고 있는 것을 확인할 필요가 있습니다.보통 다른 유닛과의 상호작용이 포함됩니다.여기서 "유닛"은 클래스 또는 응용 프로그램의 더 큰 하위 집합을 의미합니다.

업데이트:

검증뿐만 아니라 스텁에도 해당된다고 생각합니다.콜라보레이터 클래스의 메서드를 스텁하면 유닛테스트는 어떤 의미에서 구현에 의존하게 됩니다.그렇게 하는 것은 일종의 단위 테스트의 특성입니다.Mockito는 검증과 마찬가지로 스텁에 관한 것이기 때문에, Mockito를 사용하고 있는 것은, 이러한 의존 관계를 극복해 나가는 것을 의미합니다.

지금까지의 경험으로 보면, 수업의 실시를 변경하면, 그 단위 테스트의 실시를 일치시키기 위해서 변경할 필요가 있는 경우가 많습니다.단, 일반적으로 클래스에 어떤 유닛테스트가 있는지 인벤토리를 변경할 필요는 없습니다.물론 이전에 테스트에 실패한 조건이 변경되어 있지 않은 경우는 예외입니다.

이게 유닛 테스트의 목적입니다.이러한 콜라보레이터 클래스의 사용 방법에 의존하지 않는 테스트는 실제로 하위 시스템 테스트 또는 통합 테스트입니다.물론, 이것들은 JUnit로도 자주 쓰여지고 조롱의 사용도 수반된다.제 생각에 JUnit은 모든 종류의 테스트를 제작할 수 있는 제품에 대한 끔찍한 이름입니다.

David의 답변은 물론 맞지만 왜 당신이 이것을 원하는지는 잘 설명되지 않는다.

기본적으로 유닛 테스트에서는 유닛의 기능을 개별적으로 테스트합니다.입력이 예상 출력을 생성하는지 여부를 테스트합니다.때로는 부작용도 검사해야 합니다.한마디로 verify를 사용하면 그렇게 할 수 있습니다.

예를 들어 DAO를 사용하여 데이터를 저장해야 하는 비즈니스 로직이 있습니다.DAO를 인스턴스화하고 비즈니스 로직에 연결한 다음 데이터베이스 내에서 원하는 데이터가 저장되었는지 확인하는 통합 테스트를 사용할 수 있습니다.더 이상 단위 테스트가 아닙니다.

또는 DAO를 조롱하고 예상대로 호출되는지 확인할 수 있습니다.mockito를 사용하면 어떤 것이 호출되었는지, 호출 빈도를 확인할 수 있으며, 특정 방법으로 호출되도록 파라미터에 매처도 사용할 수 있습니다.

이와 같은 유닛 테스트의 단점은 실제로 테스트를 구현과 연계하여 리팩터링을 조금 더 어렵게 한다는 것입니다.반면에 좋은 디자인 냄새는 그것을 적절하게 연습하는 데 필요한 코드의 양이다.테스트가 매우 길어야 하는 경우 설계에 문제가 있을 수 있습니다.따라서 많은 부작용/복잡한 상호작용을 테스트해야 하는 코드는 아마도 좋은 것이 아닐 것입니다.

좋은 질문입니다!그 근본 원인은 다음과 같습니다.유닛 테스트뿐만 아니라 JUnit도 사용하고 있습니다.그래서 질문은 나누어야 한다.

  • 모키토 쓸까?verify()는 통합 테스트(또는 유닛보다 높은 테스트)에서 사용할 수 있습니까?
  • 모키토 쓸까?verify()는 내 블랙박스 유닛에 있습니까?
  • 모키토 쓸까?verify()를 화이트박스 유닛에 삽입할 수 있습니까?

따라서 유닛보다 높은 테스트를 무시한다면 "Mockito와 화이트 박스 유닛 테스트 사용"이라는 질문을 바꿀 수 있습니다.verify()는 유닛 테스트와 구현 사이에 훌륭한 조합을 만듭니다.그레이 박스 유닛 테스트를 할 수 있는지, 그리고 이 테스트에 사용할 수 있는 경험 규칙을 알려주세요.

이제 이 모든 것을 단계별로 살펴보겠습니다.

*- Mockito로 할까요?verify()는 통합 테스트(또는 유닛보다 높은 테스트)에서 사용할 수 있습니까?* 대답은 분명히 아니라고 생각합니다.게다가, 이것에 모크를 사용해서는 안 됩니다.테스트는 가능한 한 실제 응용 프로그램에 가까워야 합니다.애플리케이션의 격리된 부분이 아닌 완전한 사용 사례를 테스트합니다.

*블랙박스 vs 화이트박스 유닛 테스트* 실제로 수행하는 블랙박스 방식을 사용하는 경우 예상되는 출력을 받을 수 있는 (모든 동등성 클래스) 입력, 상태 및 테스트를 제공합니다.이 접근법에서는 일반적으로 mocks를 사용하는 것은 정당화됩니다(그들이 옳은 일을 하고 있는 것처럼 흉내낼 뿐 테스트하고 싶지 않습니다). 하지만 Mockito에게 전화합니다.verify()는 불필요한 값입니다.

실제로 수행하는 작업에 화이트박스 방식을 사용할 경우 유닛의 동작을 테스트하는 것입니다.이 접근법에서는 모키토에게 전화한다.verify()는 필수입니다.유닛이 예상대로 동작하는지 확인해야 합니다.

회색 상자 테스트에 대한 엄지손가락 규칙 화이트 상자 테스트의 문제는 높은 결합을 만든다는 것입니다.가능한 해결책 중 하나는 화이트 박스 테스트가 아닌 그레이 박스 테스트를 실행하는 것입니다.이것은 블랙박스 테스트와 화이트박스 테스트의 조합입니다.화이트 박스 테스트와 같이 실제로 유닛의 동작을 테스트하고 있지만, 일반적으로 가능한 한 구현에 구애받지 않습니다.가능하면 블랙박스의 경우와 같이 체크만 하면 됩니다.출력이 기대한 대로라고 단언하면 됩니다.그래서 당신의 질문의 본질은 그것이 언제 가능한지이다.

이거 진짜 어렵다.좋은 예는 없지만 예를 들어 드릴 수는 있습니다.위에 equals() vs equals를 지정한 경우Ignore Case()는 Mockito를 호출해서는 안 됩니다.verify는 출력만 아사트합니다.할 수 없는 경우는, 할 수 있을 때까지, 작은 유닛에 코드를 분석합니다.한편, @Service가 몇 개 있고, 기본적으로 @Service에 래퍼되어 있는 @Web-Service를 쓰고 있다고 가정합니다.이것에 의해, 모든 콜이 @Service에 위임됩니다(및 에러 처리가 몇개 더 이루어집니다).이 경우 모키토에게 전화합니다.verify()는 필수입니다.@Serive에 대해 수행한 모든 체크를 복제하지 마십시오.정확한 파라미터 리스트를 사용하여 @Service에 콜하고 있는지 확인합니다.

고전적인 접근의 관점에서 보면 전적으로 옳은 말씀입니다.

  • 처음에 어플리케이션의 비즈니스 로직을 작성(또는 변경)한 후 (어댑트)테스트(테스트-라스트 어프로치)로 커버하는 경우, 입력과 출력의 체크 이외의 소프트웨어 동작에 대해 테스트에 통지하는 것은 매우 힘들고 위험합니다.
  • 테스트 중심의 접근방식을 실천하고 있는 경우, 테스트의 작성, 변경 및 소프트웨어 기능의 사용 예에 대한 반영이 가장 먼저 이루어집니다.구현은 테스트에 따라 달라집니다.즉, 다른 컴포넌트의 메서드에 의존하거나 특정 횟수라고 하는 등 특정 방법으로 소프트웨어를 구현하고 싶은 경우가 있습니다.그곳이 모키토가 있는 곳이다.verify()는 편리합니다!

중요한 것은 범용 툴이 없다는 것입니다.소프트웨어의 종류, 규모, 회사의 목표와 시장 상황, 팀 스킬 및 기타 많은 것들이 특정 사례에서 어떤 접근방식을 사용할지 결정하는 데 영향을 미칩니다.

모키토를 좋아하지 않는 경우가 대부분입니다.verify. 이는 테스트된 장치가 수행하는 모든 작업을 검증하는 데 사용되기 때문에 테스트에서 변경 사항이 있을 경우 테스트를 조정해야 합니다.하지만, 저는 그게 문제라고 생각하지 않아요.메서드의 테스트를 변경하지 않고 메서드의 기능을 변경할 수 있다면 기본적으로 메서드가 수행하는 모든 작업을 테스트하지 않는 테스트를 작성해야 합니다. 변경 사항을 테스트하지 않도록 하기 때문입니다.그리고 그것은 잘못된 사고방식이다.

정말로 문제가 되는 것은, 사용의 방법을 변경할 수 있고, 기능 전체를 커버하는 유닛 테스트가 실패하지 않는 경우입니다.즉, 변경의 의도가 무엇이든 변경의 결과는 테스트 대상이 되지 않습니다.

그렇기 때문에 가능한 한 조롱하고 싶습니다.데이터 오브젝트도 조롱합니다.이 경우 verify를 사용하여 다른 클래스의 올바른 메서드가 호출되었는지 확인할 수 있을 뿐만 아니라 전달되는 데이터가 해당 데이터 개체의 올바른 메서드를 통해 수집되는지 확인할 수 있습니다.또한 콜을 완료하려면 콜이 발생하는 순서를 테스트해야 합니다.예: DB 엔티티 개체를 수정한 후 저장소를 사용하여 저장하는 경우 개체의 설정자가 올바른 데이터로 호출되고 저장소의 저장 메서드가 호출되는지 확인하는 것만으로는 충분하지 않습니다.잘못된 순서로 호출되어도 메서드가 제대로 작동하지 않습니다.그래서 나는 모키토를 쓰지 않는다.verify 단, 모든 mocks를 사용하여 inOrder 객체를 만들고 대신 inOrder.verify를 사용합니다.그리고 완성하고 싶다면 모키토에게도 전화해야 합니다.verify NoMoreInteractions는 마지막에 모든 mocks를 전달합니다.그렇지 않으면 누군가가 테스트하지 않고 새로운 기능/동작을 추가할 수 있습니다.즉, 커버리지 통계는 100%가 될 수 있지만, 아직 주장 또는 검증되지 않은 코드를 축적하고 있는 것을 의미합니다.

어떤 사람들이 말하듯이

  1. 때때로 당신은 당신이 주장할 수 있는 직접적인 결과를 얻지 못할 수 있다.
  2. 경우에 따라서는 테스트된 메서드가 (당신이 조롱하고 있는) 올바른 간접 출력을 공동작업자에게 전송하고 있는지 확인해야 할 수도 있습니다.

리팩터링 시 테스트 파손에 대한 우려에 대해서는 Mock/Stub/Spy 사용 시 어느 정도 예상되고 있습니다.Mockito와 같은 특정 구현에 관한 것이 아니라 정의에 의한 것입니다.그러나 이렇게 생각할 수 있습니다.방식의 동작방식에 큰 변화를 가져오는 리팩터링을 실시할 필요가 있는 경우에는 TDD 접근법으로 리팩터링을 실시하는 것이 좋습니다.즉, 먼저 테스트를 변경하여 새로운 동작을 정의하고(테스트에 불합격), 후 변경을 실시하여 테스트를 재합격할 수 있습니다.

언급URL : https://stackoverflow.com/questions/12539365/when-to-use-mockito-verify

반응형