단위 테스트에서 리포지토리를 두 ​​번 만드는 이유는 무엇입니까?


10

다른 날에는 Unit Testing에 대해 조금 읽고 있었고 사람들이 저장소 인터페이스 (예 :) IExampleRepository를 만든 다음 실제 저장소 ( public class ExampleRepository : IExampleRepository)와 단위 테스트에 사용할 저장소 ( ) 를 만드는 몇 가지 예를 보았습니다 FakeExampleRepository : IExampleRepository.

에서 다른 Linq 쿼리를 사용 IExampleRepository하여와 동일한 메소드를 구현했습니다 ExampleRepository.

여기서 정확히 목표는 무엇입니까? 코드 단위 테스트의 한 부분이 메소드가 올바르게 작동하는지 확인하는 것이라고 생각 했습니까? 그러나 두 가지 완전히 다른 쿼리를 사용하면 하나는 '실제'에 대한 것이고 하나는 테스트에 어떤 의미가 있습니까?

답변:


8

단위 테스트의 목표 중 하나는 한 번에 하나의 클래스와 방법 만 테스트하는 것입니다. 저장소 자체가 테스트 중이 아닌 경우 일반적으로 메소드 / 클래스의 논리를 테스트하기 위해 어떤 방식 으로든이를 모의합니다.

'실제'리포지토리 *로 테스트해야한다고 말했지만 일반적으로 통합 / 시스템 테스트에서 수행됩니다.

* 예를 들어 프로덕션 DB와 같은 테스트를 위해 설정된 repo에서와 같이 분명히 실제입니다.


따라서 단위 테스트에서 올바른 값을 반환하는지 확인하기 위해 메서드 자체를 테스트하지 않을 것입니다 (가짜 / 모의 데이터 세트를 기반으로)?
jao

예. 메소드 자체 만 테스트하지만 메소드 의 코드 다른 오브젝트의 코드는 다른 단위 테스트에서 다루어야하며 여러 오브젝트의 상호 작용은 통합 테스트 또는 상위 레벨 테스트
jk

1
알았으므로 올바르게 이해하면 저장소를 단위 테스트 할 때 원래 저장소를 사용해야합니다. 컨트롤러에 대한 유닛 테스트를 작성할 때 (Asp.Net MVC의 경우)
jao

4
@Theomax 상황에 따라 다릅니다 : 귀하 가 아닌 소프트웨어 구성 요소를 단위 테스트 하는 경우 모의를 사용하는 것이 가장 좋습니다. 저장소를 단위 테스트하지 않고 다른 것이 있다는 것이 정당화됩니다. ExampleRepository
Andres F.

5
@Theomax AndresF.의 의견을 확장하려면 : 단위 테스팅 ExampleRepository인 경우 실제를 사용하십시오. 단위 테스트 RepositoryController인 경우 사전 지정된 값을 반환 하는 사용해야 FakeExampleRepository합니다. 이 방법에의 버그 섬뜩한이 경우 ExampleRepository, 단지 단위 테스트가 실패합니다 - RepositoryController의 테스트는 버그가 존재하지 않습니다 알 수 있도록, 성공하는 것입니다. 컨트롤러가 실제 리포지토리를 사용했다면 둘 다 실패하고 1 버그 또는 2가 있는지 알 수 없습니다.
Izkata

5

나는 jk의 두 가지 답변에 동의합니다. 그리고 Jan Hudec은 정말 좋은 정보를 제공합니다. 그러나 나는 조금 추가 할 것이라고 생각했습니다.

첫 번째 질문 ( "여기에서 목표는 정확히 무엇입니까?")이 중요합니다. 설명하는 경우 실제 목표는 IExampleRepository저장소 구현을 테스트하지 않고 인터페이스를 사용하는 클래스를 테스트하는 것입니다. 를 작성하면 FakeExampleRepository실제 저장소 클래스의 세부 사항에 대해 걱정하지 않고 해당 클라이언트 클래스를 테스트 할 수 있습니다.

설정하려는 객체가 테스트를 어렵게 만드는 경우 (예 : 파일 시스템 액세스, 웹 서비스 호출 또는 데이터베이스와의 통신)에는 특히 그렇습니다. 인터페이스 (및 기타 기술)를 사용하면 커플 링을 낮게 유지할 수 있습니다. 따라서 클래스 X는 인터페이스에 대해서만 알아야하고 구현 세부 사항에 대해서는 알 필요가 없습니다. 목표는 수업 X이 올바른 일을하도록하는 것입니다.

조롱 (또는 스터 빙, 페이 킹, 미묘한 차이가 있음)은 단위 테스트 및 TDD를위한 강력한 도구입니다. 그러나 이러한 구현을 수동으로 작성하고 유지 관리하는 것은 어려울 수 있습니다. 따라서 대부분의 언어에는 이제 모의 라이브러리가 있습니다. C #을 사용하고 있으므로 Moq 는 간단하고 강력하기 때문에 권장 합니다. 그런 다음 모의 구현을 위해 추가 코드를 작성하지 않고도 인터페이스를 테스트 할 수 있습니다.


the real objective is to test the classes that are utilizing the IExampleRepository interface그것은 사실이 아닙니다. 목표는 IExampleRepository와 독립적 으로 테스트하는 것 입니다. 좋은 격리 프레임 워크를 추천하면 +1입니다.
StuperUser

1
동의하지 않습니다. IExampleRepository테스트중인 클래스가 해당 인터페이스에 연결되어 있기 때문에 독립적이지 않습니다 . 그러나 인터페이스의 구현 과 는 무관 합니다. 나는 내 설명이 아마도 조금 더 훌륭한 것을 사용할 수 있음을 인정할 것이다. :)
Allan

5

여기서 정확히 목표는 무엇입니까?

격리.

단위의 아이디어는 가능한 가장 작은 테스트 테스트 단위 코드를. 테스트의 다른 모든 프로덕션 코드와 분리 하여이를 수행합니다 .

가짜 클래스를 만들면 테스트중인 클래스는 유일한 프로덕션 코드입니다.

가짜 저장소를 올바르게 작성하고 테스트에 실패하면 테스트중인 코드에 문제가 있음을 알 수 있습니다. 이것은 무료 진단의 혜택을 제공합니다.

@Allan이 제안한 Moq 와 같은 격리 프레임 워크 를 살펴보면 이러한 가짜를 신속하게 생성하여 테스트 조건을 설정하고이를 사용하여 주장 할 수 있습니다.


가짜, 모의 객체와 스텁에 대한 자세한 내용은 다음과 같습니다 stackoverflow.com/questions/346372/...
StuperUser

4

단위 테스트에 모의 인스턴스를 제공하려는 이유는 세 가지입니다.

  1. 테스트의 범위를 제한하여 테스트가 뎁스 피의 버그의 영향을받지 않도록 할 수 있습니다. 테스트가 아직 완료되지 않았거나 안정적이지 않거나 다른 사람의 버그가 테스트에 영향을 미치지 않기를 바랍니다.
  2. 피의자는 설정하기가 복잡합니다. 예를 들어 실제 데이터 계층은 테스트 데이터베이스를 설정해야하기 때문에 데이터 액세스 계층은 종종 조롱됩니다. 실제 데이터 액세스 계층을 테스트해야하지만 다른 것을 디버깅 할 때 비용이 많이 드는 설정을 제한 할 수 있습니다.
  3. 종속 클래스가 다양한 종류의 오류에 올바르게 반응하는지 테스트하기 위해 모든 종류의 오답을 반환하는 모의 버전을 제공합니다. 많은 실패 모드는 재현하기가 어렵지만 여전히 테스트해야합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.