Spring Boot 如何使用NamedParameterJdbcTemplate使用mockito对服务层和Dao层进行Junit测试?

myzjeezk  于 2023-05-06  发布在  Spring
关注(0)|答案(1)|浏览(161)

我在Sping Boot 项目中有分层架构,如Controller -〉Service -〉Dao。我必须编写单元测试用例来检查所有功能。我想为服务层和Dao层编写单元测试用例。服务层内部调用3个DAO方法。
目前,我正在尝试为服务层及其内部调用的Dao方法编写测试用例,但它给出了空指针异常。

我的测试代码如下。执行此测试用例后,我在GeneratorRepository Dao类中的“namedParameterJdbcTemplate.queryForObject(existingUtQuery,namedParameters,GeneratorRowMapper)”上获得空指针异常。我已经在测试类的Response 1测试方法中初始化了'generatorRepository = new GeneratorRepository()and uTService = new UTService()',否则会给予空指针异常。

@ExtendWith(MockitoExtension.class)
public class GenerationApplicationTests {

    @InjectMocks
    private GeneratorRepository generatorRepository;
    
    @Mock
    private  NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    
    @Autowired
    private UTService uTService;
    
    
    @Test
    public void Response1() throws Exception {

        generatorRepository = new GeneratorRepository();
        uTService = new UTService();

        Request request = new Request("12345678", "F", 0, "A");
        Generator generator = new Generator("12345678.F","3er45FGTYH");

        System.out.println("utService  :  "+utService);

        when(generatorRepository.findExisting(request)).thenReturn(generator);
        Response response = uTService.getUT(Request);
        assertEquals("12345678.F", response.getValue());
        assertEquals("3er45FGTYH", response.getPre());
    }

}

服务类别

@Service
public class UTService {

    @Autowired
    private GeneratorRepository generatorDAO;

    @Autowired
    private TableFunctionRepository tableFunctionRepository;

    public Response getUT(Request request) throws UTNotFoundException {
        Response response = new Response();
        Generator existing = new Generator();
        TableFunction tableData = new TableFunction();
        Generator new = new Generator();
        Reasons exclusionInclusion = null;
        existing = generatorDAO.findExisting(request);
        if (existing != null) {
            response.setResponse(existing);
            return response;
        }
        tableData = tableFunctionRepository.callTableValuedFunction(request);
        if (tableData == null) {
            String exceptionMessage = Request + " not found in database";
            throw new UTNotFoundException(exceptionMessage);
        } else {
            new.setInfo(request.getId(), request.getSubId(), request.getRevisionNo(), request.getState());
            exclusionInclusion = checkExclusionInclusionCriteria(tableData);
            new.setExclusionInclusionReasonId(exclusionInclusion.getReasonCode());
            new = generateUT(tableData, exclusionInclusion, new);
            response.setResponse(new);
            generatorDAO.saveUT(new);
        }
        log.info("finished getUT");
        return response;

    }
    
}

道课

@Repository
public class GeneratorRepository 
{
    @Value("${sql.saveutiQuery}")
    private String saveUTQuery;

    @Value("${sql.existingUtiQuery}")
    private String existingUtQuery;

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    private BeanPropertyRowMapper<Generator> generatorRowMapper;

    public int saveUT(Generator generator) {
        int rowsAffected = 0;
        try {
            SqlParameterSource paramSource = new BeanPropertySqlParameterSource(generator);
            rowsAffected = namedParameterJdbcTemplate.update(saveUTQuery, paramSource);
        } catch(Exception e) {
            throw e;
        }
        return rowsAffected;
    }

    public Generator findExistingUT(Request request) {
        Generator ut = new Generator();
        try {
            SqlParameterSource namedParameters = new MapSqlParameterSource()
                    .addValue("No", request.getId(), Types.VARCHAR)
                    .addValue("Sub", request.getSubId(), Types.VARCHAR)
                    .addValue("Revision", request.getRevision(), Types.INTEGER)
                    .addValue("state", request.getState(), Types.VARCHAR);
            ut = namedParameterJdbcTemplate.queryForObject(existingUtQuery, namedParameters, GeneratorRowMapper);
        } catch (Exception e) {
            throw e;
        }
        return ut;
    }
}

@Repository
public class TableFunctionRepository {

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    private BeanPropertyRowMapper<TableFunction> tableFunctionRowMapper;

    @Value("${sql.DetailsQuery}")
    private String tableDetailsQuery;

    public TableFunction callTableValuedFunction(Request request) {
        TableFunction tableDetails = new TableFunction();
        try {
            SqlParameterSource namedParameters = new MapSqlParameterSource()
                    .addValue("No", request.getId(), Types.VARCHAR)
                    .addValue("Sub", request.getSub(), Types.VARCHAR)
                    .addValue("Revision", request.getRevision(), Types.INTEGER)
                    .addValue("state", request.getState(), Types.VARCHAR);

            tableDetails = namedParameterJdbcTemplate.queryForObject(tableDetailsQuery, namedParameters, tableFunctionRowMapper);
        } catch (Exception e) {
            throw e;
        }       
        return tableDetails;
    }
}

使用junit和mockito编写测试用例,同时覆盖service层和Dao层,应该遵循什么方法?

camsedfj

camsedfj1#

首先,当你有@autowired变量时,这意味着你需要@mock它们,如果你想得到模拟对象。
然后,如果您测试Service类,则需要为此服务使用@InjectMocks。这意味着您正在创建一个mocked服务,用于测试并向他注入您使用@mock注解或其他方式模拟的所有mock。
这里是您的测试的更新版本:

@ExtendWith(MockitoExtension.class)
public class UTServiceTest {

    @InjectMocks
    private UTService uTService;

    @Mock
    private GeneratorRepository generatorRepository;

    @Mock
    private TableFunctionRepository tableFunctionRepository;

    @Test
    public void testGetUT_whenExistingGeneratorFound_returnResponse() throws UTNotFoundException {
        // Arrange
        Request request = new Request("12345678", "F", 0, "A");
        Generator existingGenerator = new Generator("12345678.F", "3er45FGTYH");
        Response expectedResponse = new Response(existingGenerator);

        // Mock generatorRepository to return an existing generator for the given request
        when(generatorRepository.findExisting(request)).thenReturn(existingGenerator);

        // Act
        Response actualResponse = uTService.getUT(request);

        // Assert
        assertEquals(expectedResponse, actualResponse);
    }

并且可以测试异常抛出

@Test
    public void testGetUT_whenTableDataNotFound_throwUTNotFoundException() throws UTNotFoundException {
        Request request = new Request("12345678", "F", 0, "A");
        when(tableFunctionRepository.callTableValuedFunction(request)).thenReturn(null);

        assertThrows(UTNotFoundException.class, () -> uTService.getUT(request));
    }

此外,您可以在所有测试都通过时再测试一个用例,方法是将以下行添加到第一个测试用例,但为其编写第三个测试:

when(generatorRepository.findExisting(request)).thenReturn(null);

        // Mock tableFunctionRepository to return tableData for the given request
        when(tableFunctionRepository.callTableValuedFunction(request)).thenReturn(tableData);

        // Mock the generateUT method to return the expectedGenerator
        when(uTService.generateUT(tableData, exclusionInclusion, any(Generator.class)))

相关问题