2013-09-25 80 views
8

Tôi đang đối mặt với các vấn đề dịch vụ nhạo báng được tiêm bên trong các dịch vụ khác trong khung công tác Spring. Đây là mã của tôi:Các dịch vụ giả lập bên trong một dịch vụ lò xo khác với mockito

@Service("productService") 
public class ProductServiceImpl implements ProductService { 

    @Autowired 
    private ClientService clientService; 

    public void doSomething(Long clientId) { 
     Client client = clientService.getById(clientId); 
     // do something 
    } 
} 

Tôi muốn thử những ClientService bên trong thử nghiệm của tôi, vì vậy tôi thử như sau:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/spring-config.xml" }) 
public class ProductServiceTest { 

    @Autowired 
    private ProductService productService; 

    @Mock 
    private ClientService clientService; 

    @Test 
    public void testDoSomething() throws Exception { 
     when(clientService.getById(anyLong())) 
       .thenReturn(this.generateClient()); 

     /* when I call this method, I want the clientService 
     * inside productService to be the mock that one I mocked 
     * in this test, but instead, it is injecting the Spring 
     * proxy version of clientService, not my mock.. :(
     */ 
     productService.doSomething(new Long(1)); 
    } 

    @Before 
    public void beforeTests() throws Exception { 
     MockitoAnnotations.initMocks(this); 
    } 

    private Client generateClient() { 
     Client client = new Client(); 
     client.setName("Foo"); 
     return client; 
    } 
} 

Các clientService bên productService là phiên bản ủy mùa xuân, không phải là mô hình mà tôi muốn. Có thể làm những gì tôi muốn với Mockito không?

Trả lời

0

Có nhiều cách để đạt được điều này, cách dễ dàng nhất để làm điều này sẽ don't use field injection, but setter injection có nghĩa là bạn nên có:

@Autowired 
public void setClientService(ClientService clientService){...} 

trong lớp dịch vụ của bạn, sau đó bạn có thể tiêm giả của bạn với dịch vụ trong lớp thử nghiệm:

@Before 
public void setUp() throws Exception { 
    productService.setClientService(mock); 
} 

important: Nếu đây chỉ là một thử nghiệm đơn vị, xin vui lòng xem xét không sử dụng SpringJUnit4ClassRunner.class, nhưng MockitoJunitRunner.class, do đó bạn cũng có thể sử dụng trường tiêm cho các lĩnh vực của bạn.

+1

Cảm ơn, tôi đã cố gắng mà giải pháp và làm việc tốt, nhưng tôi không thể thay đổi để setter injection trong dịch vụ, vì vậy giải pháp của tôi là để loại bỏ chú thích tự động trên các thử nghiệm của tôi và tạo dịch vụ bằng tay, như sau: '@InjectMocks Sản phẩm riêng tư ProductServiceService = new ProductServiceImpl();' – br4zuca

+0

@ br4zuca bạn có thể làm điều đó với '@InjectMocks Sản phẩm dịch vụ riêng tưService', không bắt đầu hướng dẫn sử dụng, hãy giả sử ito làm điều đó. – Jaiwo99

+1

Tôi đã thử để lại mockito init 'productService' bằng' @ InjectMocks', nhưng không hoạt động vì 'ProductService' là một giao diện, nó được ném:' org.mockito.exceptions.base.MockitoException: kiểu 'ProductService' là một giao diện', vì vậy nó không thể khởi tạo được. – br4zuca

4

Bạn cần phải chú thích ProductService với @InjectMocks:

@Autowired 
@InjectMocks 
private ProductService productService; 

này sẽ bơm các ClientService giả vào ProductService của bạn.

+0

Cảm ơn Debojit, nhưng tôi nhận ra không có cách nào để sử dụng tiêm của mùa xuân kết hợp với tiêm giả của mockito ... vì vậy giải pháp của tôi là tạo ProductService bằng tay và tiêm mocks với '@ InjectMocks' như bạn đã nói , nhưng không sử dụng '@ Autowired': ' @InjectMocks riêng Sản phẩmServiceService = new ProductServiceImpl(); ' – br4zuca

+0

Điều đó thật lạ. Tôi đã sử dụng hai chú thích này cùng nhau. Bạn đã thử nghiệm nó chưa. Có ngoại lệ nào trong khi sử dụng hai trường hợp này cùng nhau không. –

+0

Có, tôi đã thử nghiệm nó rất nhiều, ngay cả với '@ InjectMocks' trên ProductService, clientService bên trong đã được tải với proxy mùa xuân thay vì đối tượng giả. Có thể phiên bản thử nghiệm mùa xuân bạn đang sử dụng khác với phiên bản tôi đang sử dụng, phiên bản của tôi là 3.0.1.RELEASE, phiên bản của bạn là gì? – br4zuca

0

Ngoài

@Autowired 
@InjectMocks 
private ProductService productService; 

Thêm phương pháp sau

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 
}