我们正在构建一个使用Spring Boot的应用程序。我们使用TestNG和Mockito编写单元测试。然而,当(…)配置时,我发现写起来很烦人,我想使用真正的组件。我开始使用@Spy组件而不是mock,这非常有效,直到我需要将间谍放入间谍中。如果可能的话,我希望避免加载Spring上下文,因为上下文的创建非常缓慢——对我来说,最多为5个类加载它似乎有些过头了。
有没有办法,我怎么能使用真实的代码而不是Mocks,并且不加载整个Spring上下文?或者我的方法是错误的,我应该先模拟所有其他类,然后再模拟测试的类?
实现这一点的另一种方法是通过构造函数注入而不是字段注入,并且可能需要对代码进行一些修改。基本上消除了测试对spring上下文的任何需求。因此与其他答案相同
要测试的类别
@Service
public class RecordServiceImpl implements RecordService
{
private final RecordRepository recordRepository;
@Autowired
public RecordServiceImpl(RecordRepository recordRepository)
{
this.recordRepository = recordRepository;
}
public Record find(String id)
{
return recordRepository.findOne(id);
}
public List<Record> findAll()
{
return recordRepository.findAll();
}
@Transactional
public Record save(Record record)
{
record.setRecordStatus("F");
return recordRepository.save(record);
}
}
测试用例
//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = {RecordServiceTestConfig.class})
public class RecordServiceTest
{
// @Autowired
private RecordRepository recordRepository = Mockito.mock(RecordRepository.class);
// @Autowired
private RecordService recordService;
@Before
public void setup()
{
Mockito.reset(recordRepository);
recordService = new RecordServiceImpl(recordRepository);
}
@Test
public void testFind()
{
Mockito.when(recordRepository.findOne(Mockito.anyString())).thenReturn(null);
Record record = recordService.find("1");
Assert.assertNull(record);
Mockito.verify(recordRepository, Mockito.times(1)).findOne(Mockito.eq("1"));
}
@Test
public void testSave()
{
Mockito.when(recordRepository.save(Mockito.any(Record.class)))
.thenAnswer(new Answer<Record>()
{
@Override
public Record answer(InvocationOnMock invocation) throws Throwable
{
Record record = (Record) invocation.getArguments()[0];
Assert.assertEquals("F", record.getRecordStatus());
return record;
}
});
Record record = new Record();
record = recordService.save(record);
Assert.assertNotNull(record);
Mockito.verify(recordRepository, Mockito.times(1)).save(Mockito.eq(record));
}
@Test
public void findAll()
{
Mockito.when(recordRepository.findAll()).thenReturn(new ArrayList<Record>());
List<Record> records = recordService.findAll();
Assert.assertNotNull(records);
Assert.assertEquals(0, records.size());
Mockito.verify(recordRepository, Mockito.times(1)).findAll();
}
}
我认为您正在使用@ContextConfiguration
和@Configuration
进行类似的搜索
要测试的类别
@Service
public class RecordServiceImpl implements RecordService
{
@Autowired
private RecordRepository recordRepository;
public Record find(String id)
{
return recordRepository.findOne(id);
}
public List<Record> findAll()
{
return recordRepository.findAll();
}
@Transactional
public Record save(Record record)
{
record.setRecordStatus("F");
return recordRepository.save(record);
}
}
测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RecordServiceTestConfig.class})
public class RecordServiceTest
{
@Autowired
private RecordRepository recordRepository;
@Autowired
private RecordService recordService;
@Before
public void setup()
{
Mockito.reset(recordRepository);
}
@Test
public void testFind()
{
Mockito.when(recordRepository.findOne(Mockito.anyString())).thenReturn(null);
Record record = recordService.find("1");
Assert.assertNull(record);
Mockito.verify(recordRepository, Mockito.times(1)).findOne(Mockito.eq("1"));
}
@Test
public void testSave()
{
Mockito.when(recordRepository.save(Mockito.any(Record.class)))
.thenAnswer(new Answer<Record>()
{
@Override
public Record answer(InvocationOnMock invocation) throws Throwable
{
Record record = (Record) invocation.getArguments()[0];
Assert.assertEquals("F", record.getRecordStatus());
return record;
}
});
Record record = new Record();
record = recordService.save(record);
Assert.assertNotNull(record);
Mockito.verify(recordRepository, Mockito.times(1)).save(Mockito.eq(record));
}
@Test
public void findAll()
{
Mockito.when(recordRepository.findAll()).thenReturn(new ArrayList<Record>());
List<Record> records = recordService.findAll();
Assert.assertNotNull(records);
Assert.assertEquals(0, records.size());
Mockito.verify(recordRepository, Mockito.times(1)).findAll();
}
}
测试类配置
@Configuration
public class RecordServiceTestConfig
{
@Bean
public RecordService recordService()
{
return new RecordServiceImpl();
}
@Bean
public RecordRepository recordRepository()
{
return Mockito.mock(RecordRepository.class);
}
}
整个测试类花费714ms来运行CCD_ 3测试花费1ms。
如果您希望使用带有Spring的testng来配置您的测试用例,那么您应该提到
@ContextConfiguration(locations={
"/context.xml","/test-context.xml"})
在类级别加载spring文件并扩展类org.springframework.test.context.testng.AbstractTestNGSpringContextTests
样品https://dzone.com/articles/spring-testing-support-testng