如何在TestNG中结合Mockito和Spring



我们正在构建一个使用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

相关内容

  • 没有找到相关文章

最新更新