我知道我不应该测试像这样的void方法,但是到目前为止,我只是通过一个简单的示例来测试Mockito.doNothing()。
我的服务班级:
@Service
public class Service{
@Autowired
private Consumer<String, String> kafkaConsumer;
public void clearSubscribtions(){
kafkaConsumer.unsubscribe();
}
}
我的测试班:
@MockBean
private Consumer<String, String> kafkaConsumer;
@Test
public void testClearSubscriptions() {
Service service = new Service();
Mockito.doNothing().when(kafkaConsumer).unsubscribe();
service.clearSubscriptions();
}
测试不断失败,并出现空指针异常。当我对其进行调试时,它将进入服务类的clearSubscription方法,并且在kafkaConsumer.unsubscribe()行中,kafkaConsumer为null。但是我嘲笑了使用者,为什么它会引发空指针异常,而我应该跳过该方法,对吗?
编辑:该类的所有声明:
@Autowired
private Consumer<String, String> kafkaConsumer;
@Autowired
private Service2 service2;
private final Object lock = new Object();
private static Logger logger = LoggerFactory.getLogger(Service.class);
private HashMap<String, String> subscribedTopics = new HashMap<>();
找出问题所在,我需要自动连接服务
您正在实例化一个新服务,Service service = new Service();
但是据我所知,您从未将模拟bean注入到新服务中。
这是我认为如果仅使用Mockito并且不需要实例化spring容器(为了便于示例而使用单个类,请勿在实际代码中执行此操作)的情况下可以执行的操作的示例:
package com.sbp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@RunWith(MockitoJUnitRunner.class) // run with mockitos runner so annotations are processed
public class MyServiceTest {
public interface Consumer<T, R> {
public void unsubscribe();
}
@Service
public class KafkaConsumer implements Consumer<String, String> {
@Override
public void unsubscribe() {
}
}
@Service
public class MyService {
@Autowired
private Consumer<String, String> kafkaConsumer;
public void clearSubscriptions() {
kafkaConsumer.unsubscribe();
}
}
@Mock // tell mockito that this is a mock class - it will instantiate for you
private Consumer<String, String> kafkaConsumer;
@InjectMocks // tell mockito to inject the above mock into the class under test
private MyService service = new MyService();
@Test
public void testClearSubscriptions() {
service.clearSubscriptions();
Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe();
}
}
如果您需要使用MockBean或不使用and依赖项通过Spring获得示例,请告诉我,我可以发布。
更新:使用spring junitRunner和spring boot的mockbean注释添加示例
package com.sbp;
import com.sbp.MyServiceTest.TestContext.MyService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) // run with spring
@SpringBootTest(classes = MyServiceTest.TestContext.class) // make it a spring boot test so @MockBean annotation is processed, provide a dummy test context class
public class MyServiceTest {
public interface Consumer<T, R> {
public void unsubscribe();
}
@Configuration
public static class TestContext {
@Service
public class KafkaConsumer implements Consumer<String, String> {
@Override
public void unsubscribe() {
}
}
@Service
public class MyService {
@Autowired
private Consumer<String, String> kafkaConsumer;
public void clearSubscriptions() {
kafkaConsumer.unsubscribe();
}
}
}
@MockBean // this will create a mockito bean and put it in the application context in place of the Kafka consumer bean defined in the TestContext class
private Consumer<String, String> kafkaConsumer;
@Autowired // inject the bean from the application context that is wired with the mock bean
private MyService myService;
@Test
public void testClearSubscriptions() {
myService.clearSubscriptions();
Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句