模拟服务与另一个弹簧服务与mockito

时间:2013-09-25 11:41:08

标签: java spring junit4 mockito spring-test

我面临着在Spring框架内模拟注入其他服务的服务的问题。这是我的代码:

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

    @Autowired
    private ClientService clientService;

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

我想在我的测试中嘲笑ClientService,所以我尝试了以下内容:

@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;
    }
}

clientService里面productService是Spring代理版本,而不是我想要的模拟。我可以用Mockito做我想做的事吗?

4 个答案:

答案 0 :(得分:4)

您需要使用ProductService注释@InjectMocks

@Autowired
@InjectMocks
private ProductService productService;

这会将ClientService模拟注入您的ProductService

答案 1 :(得分:1)

有更多方法可以实现这一目标,最简单的方法是don't use field injection, but setter injection,这意味着您应该:

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

在您的服务类中,然后您可以将模拟注入测试类中的服务:

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

important:如果这只是一项单元测试,请考虑不要使用SpringJUnit4ClassRunner.class,而是MockitoJunitRunner.class,这样您也可以使用字段注入。

答案 2 :(得分:1)

我建议您用 Test target 注释 @InjectMock

目前

    @Autowired
    private ProductService productService;

    @Mock
    private ClientService clientService;

改为

    @InjectMock
    private ProductService productService;

    @Mock
    private ClientService clientService;

如果你仍然有 MockingService 的 NullPointerException => 你可以使用 Mockito.any() 作为参数。 希望能帮到你。

答案 3 :(得分:0)

除了

@Autowired
@InjectMocks
private ProductService productService;

添加以下方法

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}
相关问题