2015-06-11 11 views
29

Ví dụ tôi có xử lý:Tôi có thể thử phương pháp của lớp @InjectMocks như thế nào?

@Component 
public class MyHandler { 

    @AutoWired 
    private MyDependency myDependency; 

    public int someMethod() { 
    ... 
    return anotherMethod(); 
    } 

    public int anotherMethod() {...} 
} 

để thử nghiệm nó tôi muốn viết một cái gì đó như thế này:

@RunWith(MockitoJUnitRunner.class} 
class MyHandlerTest { 

    @InjectMocks 
    private MyHandler myHandler; 

    @Mock 
    private MyDependency myDependency; 

    @Test 
    public void testSomeMethod() { 
    when(myHandler.anotherMethod()).thenReturn(1); 
    assertEquals(myHandler.someMethod() == 1); 
    } 
} 

Nhưng nó thực sự gọi anotherMethod() bất cứ khi nào tôi cố gắng để thử nó. Tôi nên làm gì với myHandler để thử phương pháp của nó?

+0

Nếu bạn muốn kiểm tra myhandler, bạn shouldn 'm giả lập phương pháp riêng của nó (kể từ khi bạn muốn kiểm tra xử lý của bạn, không phải là giả). Có lý do cụ thể nào khiến bạn cần phải làm như vậy không? – Nitek

Trả lời

55

Đầu tiên tất cả các lý do để chế nhạo các phương thức MyHandler có thể như sau: chúng ta đã thử nghiệm anotherMethod() và nó có logic phức tạp, vậy tại sao chúng ta cần kiểm tra lại nó (như một phần của someMethod()) nếu chúng ta chỉ có thể gọi là verify?
Chúng ta có thể làm điều đó thông qua:

@RunWith(MockitoJUnitRunner.class} 
class MyHandlerTest { 

    @Spy 
    @InjectMocks 
    private MyHandler myHandler; 

    @Mock 
    private MyDependency myDependency; 

    @Test 
    public void testSomeMethod() { 
    doReturn(1).when(myHandler).anotherMethod(); 
    assertEquals(myHandler.someMethod() == 1); 
    verify(myHandler, times(1)).anotherMethod(); 
    } 
} 

Lưu ý: trong trường hợp đối tượng 'gián điệp' chúng ta cần phải sử dụng doReturn thay vì thenReturn (ít lời giải thích là here)

0

Trong mã của bạn, bạn không thử nghiệm MyHandler. Bạn không muốn thử những gì bạn đang thử nghiệm, bạn muốn gọi phương thức thực tế của nó. Nếu MyHandler có phụ thuộc, bạn giả sử chúng.

Something như thế này:

public interface MyDependency { 
    public int otherMethod(); 
} 

public class MyHandler { 
    @AutoWired 
    private MyDependency myDependency; 

    public void someMethod() { 
    myDependency.otherMethod(); 
    } 
} 

Và trong thử nghiệm:

private MyDependency mockDependency; 
private MyHandler realHandler; 

@Before 
public void setup() { 
    mockDependency = Mockito.mock(MyDependency.class); 
    realHandler = new MyHandler(); 
    realhandler.setDependency(mockDependency); //but you might Springify this 
} 

@Test 
public void testSomeMethod() { 

    //specify behaviour of mock 
    when(mockDependency.otherMethod()).thenReturn(1); 

    //really call the method under test 
    realHandler.someMethod(); 
} 

Vấn đề là để thực sự gọi phương thức dưới kiểm tra, nhưng thử bất kỳ phụ thuộc họ có thể có (ví dụ gọi phương pháp khác các lớp học)

Nếu những lớp học khác là một phần của ứng dụng của bạn, thì họ sẽ có các bài kiểm tra đơn vị riêng của mình.

LƯU Ý mã trên có thể được rút ngắn với nhiều chú thích, nhưng tôi muốn làm cho nó rõ ràng hơn vì lợi ích của lời giải thích (và tôi cũng không thể nhớ những gì các chú thích là :))

+0

Tạo một thể hiện trong khi sử dụng IOC mùa xuân. Bạn không được hưởng lợi từ IOC mùa xuân. Giả sử tôi phải tiêm một dịch vụ khác. Tôi không thể làm được điều đó. Tôi phải tạo một thể hiện. –

Các vấn đề liên quan