1

我写了一个测试用例,但我在该return KeyHolder.getKey()行得到一个空指针异常。

我的测试用例如下所示:

@InjectMocks
private UserDAOImpl userDAO;

@Mock
private JdbcTemplate jdbcTemplate;

@Mock
private KeyHolderFactory keyHolderFactory;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    ReflectionTestUtils.setField(userDAO, "jdbcTemplate", jdbcTemplate);
}

@Test
public void testCreateUser() {

    KeyHolder keyHolder = mock(GeneratedKeyHolder.class);

    when(keyHolderFactory.newKeyHolder()).thenReturn(keyHolder);

    User user = getUserInfo();

    Map<String,Object> map = new HashMap<>();
    map.put("id",1L);
    when(keyHolder.getKeys()).thenReturn(map);
    when(keyHolder.getKey()).thenReturn(1L);

    when(jdbcTemplate.update(Mockito.any(PreparedStatementCreator.class), Mockito.any(KeyHolder.class))).thenReturn(1);

    assertEquals(1L, userDAO.createUser(user));
}

该方法如下所示:

 @Override
  public long createUser(User user) {

KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
  PreparedStatement ps = connection
      .prepareStatement("insert into user (address, first_name,last_name, email, password, phone_number, is_init, is_system_admin, created_at)"
              + " values( ?, ?, ?, ?, ?, ?, ?, ?,?)",
          Statement.RETURN_GENERATED_KEYS);
  ps.setString(1, user.getAddress());
  ps.setString(2, user.getFirstName());
  ps.setString(3, user.getLastName());
  ps.setString(4, user.getEmail());
  ps.setString(5, user.getPassword());
  ps.setString(6, user.getPhone());
  ps.setBoolean(7, user.isActive());
  ps.setBoolean(8, user.isSystemAdmin());
  ps.setDate(9, new Date(Date.from((user.getCreatedAt().toInstant())).getTime()));

  return ps;
}, keyHolder);

return (long) keyHolder.getKey();
  }

我创建了一个界面KeyHolderFactory

public interface KeyHolderFactory {
KeyHolder newKeyHolder();
}

而这个接口的实现如下:

public class GeneratedKeyHolderFactory implements KeyHolderFactory {

public KeyHolder newKeyHolder() {
    return new GeneratedKeyHolder();
  }
}

有人可以帮我找到解决方案吗?

4

1 回答 1

1

你的问题是下一个:

在测试课中,您有 Mocked bin KeyHolderFactory,这是正确的。然后你创建 mocked KeyHolder,描述它的行为并在被问到时KeyHolderFactory返回。KeyHolder一切看起来都不错,除了下一个:

在您的代码类方法上,您使用创建新KeyHolder方法new GeneratedKeyHolder(),并且这个新方法KeyHolder与您在测试类中拥有的那些模拟实例无关。它是完全不同的对象。在您的测试类中的那个 - 是一个模拟,并将遵循您的场景。但是,在您测试的类方法中,那个是另一个对象,当您执行时,它当然不知道要做什么keyHolder.getKey()

解决方案 :

您已经注入KeyHolderFactory了测试并很好地配置了它的行为。只需将它也注入您的测试类并在您的方法中使用它来创建KeyHolderusingkeyHolderFactory.newKeyHolder()而不是new GeneratedKeyHolder()

于 2018-07-25T12:45:30.397 回答