2013-03-18 40 views
8

Tôi đang viết các bài kiểm tra đơn vị sử dụng Mockito và tôi đang gặp sự cố chế nhạo các lớp được chèn vào. Vấn đề là hai trong số các lớp được tiêm cùng loại và chỉ được phân biệt bằng chú thích @Qualifier của chúng. Nếu tôi cố gắng chỉ đơn giản là giả SomeClass.class, mô phỏng đó không được tiêm và đối tượng đó là null trong các thử nghiệm của tôi. Làm thế nào tôi có thể thử các đối tượng này?Chế nhạo hai đối tượng cùng loại với Mockito

public class ProfileDAL { 

    @Inject 
    @Qualifier("qualifierA") 
    private SomeClass someClassA ; 

    @Inject 
    @Qualifier("qualifierB") 
    private SomeClass someClassB ; 

    //...various code, not important 
} 

@RunWith(MockitoJUnitRunner.class) 
public class ProfileDALLOMImplTest { 

    @InjectMocks 
    private ProfileDALLOMImpl profileDALLOMImpl = new ProfileDALLOMImpl(); 

    @Mock 
    private SomeClass someClassA; 
    @Mock 
    private SomeClass someClassB; 

    private SomeResult mockSomeResult = mock(SomeResult.class); 

    @Test 
    public void testSomeMethod() { 
     when(someClassA .getSomething(any(SomeArgment.class)).thenReturn(mockSomeResult); 
     Int result = profileDALLOMImpl.someTest(This isn't relevant); 
    } 

} 
+0

Làm thế nào để mã kiểm tra của bạn trông như thế nào? Tôi luôn gọi một cách rõ ràng là “Mockito.mock (SomeClass.class)” để tạo ra các mocks của tôi, tránh việc kiểm tra đơn vị của tôi bất kỳ phép thuật nào được cung cấp bởi các chú thích. Bạn sẽ có thể làm như vậy, nếu bạn tiêm phụ thuộc của bạn thông qua constructor hoặc setters. Có lý do chính đáng nào không phải vậy? – rcomblen

+0

Bạn có thể chứng minh việc tiêm các phụ thuộc này mà không cần sử dụng @InjectMocks không? Tôi đã cập nhật câu hỏi của mình để minh họa cách thử nghiệm của tôi được thiết lập. – tamuren

Trả lời

0

Nếu bạn không sử dụng chú thích, bạn sẽ có được một cái gì đó giống như

public class MyClass { 
    private MyDependency myDependency; 

    public void setMyDependency(MyDependency myDependency){ 
     this.myDependency = myDependency; 
    } 
} 

import org.junit.Before; 
import org.junit.Test; 

import static org.mockito.Mockito.*; 

public class MyTest { 

    private MyClass myClass; 
    private MyDependency myDependency; 

    @Before 
    public void setUp(){ 
     myClass = new MyClass(); 
     myDependency = mock(MyDependency.class); 
     myClass.setMyDependency(myDependency); 
    } 

    @Test 
    public void test(){ 
     // Given 

     // When 

     // Then 
    } 
} 

Bạn có thể làm chỉ là tương tự nếu đối tượng của bạn đã phụ thuộc của nó quy định thông qua constructor thay hơn thông qua setter. Tôi đoán khuôn khổ tiêm phụ thuộc của bạn có thể chú thích các bộ định cư giống như cách bạn chú thích các trường riêng tư, nhưng bây giờ các thử nghiệm của bạn không dựa vào bất kỳ khuôn khổ tiêm phụ thuộc nào.

+0

Tôi không thể thách thức bằng cách sử dụng khung tiêm phụ thuộc. Đó là một quyết định thiết kế không nằm trong tay tôi. – tamuren

9

Tôi đã thử chế nhạo hai đối tượng có cùng loại với Mockito 1.9.5 bằng JUnit và nó hoạt động.

Xem: http://static.javadoc.io/org.mockito/mockito-core/1.9.5/org/mockito/InjectMocks.html

thông tin loại có liên quan từ doc:

"Field tiêm; mocks đầu tiên sẽ được giải quyết theo loại, sau đó, nếu có nhiều tài sản cùng loại, bởi các trận đấu của tên trường và tên giả. "

Và cái này mà dường như để nói rằng bạn nên làm cho tên giả phù hợp với tên trường cho tất cả các mocks của bạn khi bạn có hai của cùng một loại:

"Lưu ý 1: Nếu bạn có các lĩnh vực với cùng loại (hoặc cùng xóa), tốt hơn nên đặt tên cho tất cả các trường có chú thích là @Mock với các trường phù hợp, nếu không Mockito có thể bị lẫn lộn và việc tiêm sẽ không xảy ra. "

Có lẽ cái sau này đang cắn bạn?

1

Chỉ cần xác nhận những gì Splonk chỉ ra và nó hoạt động theo cách đó trong Mockito 1.9.5, ngay sau khi tôi loại bỏ một trong các lớp mô phỏng, nó không thành công.

Vì vậy, trong trường hợp của bạn, hãy chắc chắn bạn có cả các lớp chế giễu với tên giống như trong lớp trong thử nghiệm của bạn:

@Mock 
private SomeClass someClassA; 
@Mock 
private SomeClass someClassB; 
Các vấn đề liên quan