简体   繁体   English

使用 mockito 在另一个 spring 服务中模拟服务

[英]Mock services inside another spring service with mockito

I'm facing problems mocking services injected inside of other services within the Spring framework.我在模拟 Spring 框架内其他服务中注入的服务时遇到了问题。 Here is my code:这是我的代码:

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

    @Autowired
    private ClientService clientService;

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

I want to mock the ClientService inside my test, so I tried the following:我想在我的测试中模拟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;
    }
}

The clientService inside productService is the Spring proxy version, not the mock that I want. productService里面的clientService是Spring代理版本,不是我想要的mock。 Is it possible to do what I want with Mockito?可以用 Mockito 做我想做的事吗?

You need to annotate ProductService with @InjectMocks :您需要使用@InjectMocks注释ProductService

@Autowired
@InjectMocks
private ProductService productService;

This will inject the ClientService mock into your ProductService .这会将ClientService模拟注入您的ProductService

There are more ways to achieve this, the most easy way to do this will be don't use field injection, but setter injection which means you should have:有更多方法可以实现这一点,最简单的方法是don't use field injection, but setter injection ,这意味着您应该拥有:

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

in your service class, then you can inject your mock to the service in test class:在您的服务类中,然后您可以将模拟注入测试类中的服务:

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

important: If this is only a unit test, please consider don't use SpringJUnit4ClassRunner.class , but MockitoJunitRunner.class , so that you can also use field inject for your fields. important:如果这只是一个单元测试,请考虑不要使用SpringJUnit4ClassRunner.class ,而是MockitoJunitRunner.class ,以便您也可以为您的字段使用字段注入。

In addition to除了

@Autowired
@InjectMocks
private ProductService productService;

Add the following method添加以下方法

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

I would like to suggest you annotate the Test target with @InjectMock我建议您使用@InjectMock注释Test target

Currently目前

    @Autowired
    private ProductService productService;

    @Mock
    private ClientService clientService;

Change to更改为

    @InjectMock
    private ProductService productService;

    @Mock
    private ClientService clientService;

incase you still have NullPointerException for the MockingService => you can use Mockito.any() as arguments.如果你仍然有 MockingService 的 NullPointerException => 你可以使用 Mockito.any() 作为参数。 Hopefully, it will help you.希望它会帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM