12

我在模拟 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代理版本,不是我要的mock 。可以用 Mockito 做我想做的事吗?

4

4 回答 4

6

您需要ProductService注释@InjectMocks

@Autowired
@InjectMocks
private ProductService productService;

这会将ClientService模拟注入您的ProductService.

于 2013-09-25T11:57:42.587 回答
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,这样你也可以为你的字段使用字段注入。

于 2013-09-25T11:57:13.357 回答
1

我想建议你Test target@InjectMock

目前

    @Autowired
    private ProductService productService;

    @Mock
    private ClientService clientService;

改成

    @InjectMock
    private ProductService productService;

    @Mock
    private ClientService clientService;

如果 MockingService 仍然有 NullPointerException => 你可以使用 Mockito.any() 作为参数。希望对您有所帮助。

于 2021-03-21T16:50:35.753 回答
1

此外

@Autowired
@InjectMocks
private ProductService productService;

添加以下方法

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}
于 2017-07-25T12:02:48.313 回答