모의 프레임 워크에서 개체를 모의 하거나 감시 할 수 있습니다 . 둘 사이의 차이점은 무엇이며 언제 하나를 다른 것보다 사용해야합니까?
보면 Mockito , 예를 들어, 나는 비슷한 일을 사용하여 수행되는 것을 볼 스파이 와 모의 객체를 ,하지만 둘 사이의 구별에 관해서는 확실입니다.
모의 프레임 워크에서 개체를 모의 하거나 감시 할 수 있습니다 . 둘 사이의 차이점은 무엇이며 언제 하나를 다른 것보다 사용해야합니까?
보면 Mockito , 예를 들어, 나는 비슷한 일을 사용하여 수행되는 것을 볼 스파이 와 모의 객체를 ,하지만 둘 사이의 구별에 관해서는 확실입니다.
답변:
모의 객체는 모의 클래스를 완전히 대체하여 기록 된 값 또는 기본값을 반환합니다. "얇은 공기"에서 모의를 만들 수 있습니다. 이것은 단위 테스트 중에 주로 사용되는 것입니다.
감시 할 때 기존 개체를 가져와 일부 방법 만 "교체"합니다. 이것은 거대한 클래스가 있고 특정 메서드 (부분 모의) 만 모의하려는 경우에 유용합니다. Mockito 문서를 인용 하겠습니다 .
실제 물체의 스파이를 만들 수 있습니다. 스파이를 사용하면 실제 메서드가 호출됩니다 (메서드가 스텁되지 않은 경우).
예를 들어 레거시 코드를 처리 할 때 실제 스파이는 신중하고 가끔 사용해야합니다 .
의심스러운 경우 모의를 사용하십시오.
여기에 예제를 사용하여 설명하려고합니다.
// Difference between mocking, stubbing and spying
@Test
public void differenceBetweenMockingSpyingAndStubbing() {
List list = new ArrayList();
list.add("abc");
assertEquals(1, list.size());
List mockedList = spy(list);
when(mockedList.size()).thenReturn(10);
assertEquals(10, mockedList.size());
}
여기에서 우리는 list
하나의 요소를 추가하고 크기가 1이 될 것으로 예상되는 초기 실제 객체를 가졌습니다 .
우리는 스텁 할 방법을 지시 할 수 있다는 것을 의미하는 실제 객체를 감시 합니다 . 그래서 우리 는 실제 크기에 관계없이 10을 반환 할 스파이 개체 에 대해 스텁 메서드를 선언했습니다 .size()
요컨대, 실제 개체 를 감시 하고 일부 메서드를 스텁 합니다 .
참조 : http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
모의 객체를 사용할 때 스텁이 아닐 때 메서드의 기본 동작은 아무것도하지 않는 것입니다. 단순함은 void 메서드 인 경우 메서드를 호출 할 때 아무 작업도 수행하지 않거나 반환이있는 메서드 인 경우 null, 비어 있거나 기본값을 반환 할 수 있음을 의미합니다.
물론 스파이 개체에있는 동안 실제 메서드이므로 메서드를 스터 빙하지 않을 때 실제 메서드 동작을 호출합니다. 메소드를 변경하고 모의하려면 스텁해야합니다.
더미 오브젝트는 전달되지만 실제로 사용되지는 않습니다. 일반적으로 매개 변수 목록을 채우는 데 사용됩니다.
가짜 객체는 실제로 작동하는 구현을 가지고 있지만 일반적으로 프로덕션에 적합하지 않게 만드는 지름길을 사용합니다 (인 메모리 데이터베이스가 좋은 예입니다).
스텁 은 테스트 중에 이루어진 통화에 대해 미리 준비된 답변을 제공하며, 일반적으로 테스트를 위해 프로그래밍 된 내용 이외의 항목에는 전혀 응답하지 않습니다.
스파이 는 호출 방법에 따라 일부 정보를 기록하는 스텁입니다. 한 가지 형태는 전송 된 메시지 수를 기록하는 이메일 서비스 일 수 있습니다.
모의 는 우리가 여기서 이야기하고있는 것입니다 : 그들이받을 것으로 예상되는 호출의 사양을 형성하는 기대치로 미리 프로그래밍 된 객체.
Mockito에서 Mock Object의 인스턴스 변수에 객체를 할당하면 Mock Object에 영향을 미치지 않습니다.
그러나 Spy의 경우 Spy Object의 인스턴스 변수에 개체를 할당하면 Spy가 실시간 개체 수정처럼 동작하므로 Spy Object에 영향을줍니다.
참조 예는
@RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {
@Mock
private List<String> mockList;
@Spy
private List<String> spyList = new ArrayList();
@Test
public void testMockList() {
//by default, calling the methods of mock object will do nothing
mockList.add("test");
assertNull(mockList.get(0));
}
@Test
public void testSpyList() {
//spy object will call the real method when not stub
spyList.add("test");
assertEquals("test", spyList.get(0));
}
}