簡體   English   中英

使用Mockito模擬時無法調用以@PostConstruct注釋的方法

[英]Unable to invoke method annotated with @PostConstruct when mocked using Mockito

我正在嘗試使用Junit和Mockito為存儲庫層類編寫單元測試。 我嘲笑了提供NamedParameterJdbcOperations的基類,並試圖注入到repo類中。 在repo類中,我們從classpath上的文件加載sql查詢。 這是通過@PostConstruct注釋的方法完成的。 嘗試測試存儲庫的方法時,它無法找到或加載查詢,從而引發NullPointerException。

需要有關如何處理這種情況的幫助/建議。

PS:我不允許更改repo類的實現。

附加回購代碼和測試類以供參考。

RepositoryImpl.java

@Repository
public class RepositoryImpl extends AppJdbcImpl implements
    Repository {

private static final StudentMapper STUDENT_ROW_MAPPER = new StudentMapper();
private static final CourseMapper COURSE_ROW_MAPPER = new CourseMapper();

@Value("classpath:sql/sql1.sql")
private Resource sql1;
private String query1;

@Value("classpath:sql/sql2.sql")
private Resource sql2;
private String query2;

public RepositoryImpl() { }

public RepositoryImpl(NamedParameterJdbcOperations jdbc) {
    super(jdbc);
}

@PostConstruct
public void setUp() {
    query1 = loadSql(sql1);
    query2 = loadSql(sql2);
}

public Iterable<Course> findCoursesByStudentId(int studentId) throws
    DataAccessException {

    try {
        return jdbc().queryForObject(query1,
            ImmutableMap.of("studentId", studentId),
            COURSE_ROW_MAPPER);

    } catch (EmptyResultDataAccessException emptyResult) {
        return null;
    } catch (DataAccessException e) {
        // Need to create exception classes and throw specific exceptions
        throw e;
    }

}

public Iterable<Student> findStudentsByCourseId(int courseId) throws DataAccessException {

    try {

        return jdbc().query(query2,
            ImmutableMap.of("courseId", courseId),
            STUDENT_ROW_MAPPER);

    } catch (DataAccessException e) {
        // Need to create exception classes and throw specific exceptions
        throw e;
    }

}

private String loadSql(Resource resource) {
    try {
        return CharStreams.toString(new InputStreamReader(resource.getInputStream()));
    } catch (IOException e) {
        return null;
    }
}

}

RespositoryImplTest.java

@RunWith(MockitoJUnitRunner.class)
public class RepositoryImplTest {
@Mock
private NamedParameterJdbcOperations jdbc;

@Mock
private ResultSet resultSet;

@Mock
private StudentMapper studentMapper;

@Mock
private CourseMapper CourseMapper;

@InjectMocks
private RepositoryImpl repository;

private Student student1;
private Student student2;

private Course course1;
private Course course2;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    course1 = new Course(1, "Karate");
    course2 = new Course(2, "Riding");
    course8 = new Course(8, "Swimming");
    List<Course> courseList = Arrays.asList(course1, course2, course8);

    student1 = new Student(1, "Chuck", "Norris", 27, new Arrays.asList(course1, course2));
    student2 = new Student(2, "Bruce", "Lee", 54, new Arrays.asList(course1, course8));
    List<Student> studentList = Arrays.asList(student1, student2);

    when(jdbc.queryForObject(Matchers.anyString(), anyMap(),
        isA(StudentMapper.class)))
        .thenAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                Object[] args = invocationOnMock.getArguments();
                int queryParam = Integer.parseInt(args[0].toString());

                Iterable<Credentials> result = studentList.stream()
                .filter(d -> d.getId() == queryParam)
                .collect(Collectors.toList());

                return result;
            }
        });
}

@Test
public void findCoursesByStudentId() {
    Iterable<Course> result = repository.findCoursesByStudentId(1);
    assertNotNull(result);
}

}

在repo類中,由於query1為null引發了異常。

需要幫助以正確解決問題。

謝謝,巴魯

@RunWith(MockitoJUnitRunner.class)

您可以使用模仿啟動器而不是彈簧啟動器開始測試。 這意味着春天沒有為您提供豆類。 Mockito入門者對PostConstruct批注一無所知。

您可以在sturUp junit方法或測試方法中自行調用PostConstruct方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM