我正在使用Mockito / JUnit和Java Spring应用程序编写单元测试。我有一个Service类,该类具有一些注入的依赖项(使用@Autowired字段依赖关系注入,尽管可以更改)。其中一些是项目中的其他依赖项(例如数据访问对象),另一些是库中的各种实用程序类(例如Jackson ObjectMapper)。由于“不测试其他人的代码”的原则,我想模拟前一类的依赖关系,而不是后者。我该怎么做?
更具体地讲,假设我有这个课程:
@Service
public class MyService {
@Autowired
private MyRepository dao; //extends CrudRepository, annotated with @Repository
@Autowired
private ObjectMapper objectMapper;
//Jackson library, injected from Java @Configuration annotated class
public <...> myFunction(...){
<...do something with the above 2 objects...>
}
}
我想为此课程编写一个测试,如下所示:
public class MyServiceUnitTest {
@Mock
private MyRepository mockedRepository;
@InjectMocks
private MyService testedService;
//should inject mockedRepository and a real ObjectMapper from appconfig
<...>
}
我需要哪种类型的注释,配置文件等?目前,我的测试班级用@RunWith(SpringJUnit4ClassRunner.class)
注释,但这似乎不起作用。我还尝试过将@RunWith(SpringRunner.class)
与@SpringBootTest
结合使用,但也没有用。
答案 0 :(得分:1)
有很多方法可以做到这一点。但这就是我要解决的方法。
在MyService类中将字段注入更改为构造函数注入
private MyRepository dao;
private ObjectMapper objectMapper;
@Autowired
public MyService (MyRepository dao, ObjectMapper objectMapper) {
this.dao = dao;
this.objectMapper = objectMapper;
}
像这样编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ObjectMapper.class})
public class MyServiceUnitTest {
@Autowired
ObjectMapper objectMapper;
@Mock
private MyRepository dao; //extends CrudRepository, annotated with @Repository
private MyService myService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
myService= new MyService(dao, objectMapper);
}
@Test
public void someTest() {
.........
}
}
这样,您可以控制可以模拟服务中的哪些变量,而不必模拟哪些变量。
使用@ContextConfiguration
,可以指定需要加载的框架。这样,当您在测试中对其自动布线时,它不会失败。并且还可以使用它为测试指定仅必需的类,而不是所有内容。
您也可以通过Field Injection和@InjectMocks
来实现。但是使用构造函数注入会更好。
答案 1 :(得分:-1)
问题是您的跑步者班。
@RunWith(MockitoJUnitRunner.class)
将为您带来预期的行为。
记住要拨打电话
MockitoAnnotations.initMocks(this);
作为设置过程的一部分。