У меня возникли проблемы с попыткой издеваться над NamingEnumeration. Кроме того, я не могу получить покрытие внутри лямбда-выражения. Я также не могу получить покрытие внутри цикла while. Когда я запускаю модульный тест с помощью методов, покрытие отображается только через ldapTemplate.search, и оно пропускает то, что находится внутри лямбда-выражения, и проходит через список возврата. Я попытался добавить аннотацию Mock к объектам NamingEnumeration и Attribute. Кажется, цикл while считает, что NamingEnumeration пуст из-за отсутствия покрытия.
Следующие результаты в «Ненужные заглушки, обнаруженные в тестовом классе»: doReturn(true,false).when(enumeration).hasMore(); и doReturn(attr).when(enumeration).next();
Это мой метод Ldap
public List<MyObject> ldapQueryList(final String ldapSearch, final String key) {
List<MyObject> list = new ArrayList<>();
ldapTemplate.search("ou=User Accounts", "cn = " + ldapSearch), (Attributes attrs) -> {
NamingEnumeration<?> enumeration = attrs.get(key).getAll();
list.addAll(addToList(enumeration));
return attrs;
});
return list;
}
public List<MyObject> addToList(NamingEnumeration<?> enumeration) throws NamingException {
List<MyObject> list = new ArrayList<>();
while (enumeration.hasMoreElements()) {
final MyObject myObj = new MyObject();
final String str = (String)enumeration.nextElement();
myObj.setMyString(str);
list.add(myObj);
}
enumeration.close();
return list;
}
Это модульный тест
@RunWith(MockitoJUnitRunner.class)
public class LdapQueryDaoTest {
@Mock
private LdapTemplate ldapTemplate;
@InjectMocks
private LdapDao ldapDao;
@Mock
private NamingEnumeration<?> enumeration;
@Mock
private Attribute attr;
@Test
public void ldapQueryList() throws DataAcesExcp, NamingException {
List<String> searchResult = Collections.singletonList("search result");
when(ldapTemplate.search( Mockito.anyString(), Mockito.anyString(), ArgumentMatchers.<AttributesMapper<String>> any())).thenReturn(searchResult);
List<EmployeeVo> responseEntity = ldapDao.ldapQueryList(Const.EMPLOYEE_ID, "myLdapObj");
Assert.assertNotNull(responseEntity);
}
@Test
public void addToList() throws NamingException {
doReturn(true,false).when(enumeration).hasMore();
doReturn(attr).when(enumeration).next();
Assert.assertNotNull(ldapQueryDaoImpl.addToList(enumeration));
}
}
Я думаю, что исправил это, он должен был вернуть строку
Вы имеете в виду doReturn(attr).when(enumeration).next(); Да, это неправильный тип, я пропустил это ;)




I'm having trouble trying to mock the NamingEnumeration.
Вместо этого рассмотрите возможность использования реального перечисления. По сути, вы должны только издеваться над объектами, которые слишком сложны для создания самостоятельно (списки, итераторы и перечисления являются примерами вещей, которые не являются таковыми).
Also, I cannot get the coverage to go inside of the lambda expression.
Он работает так, как ожидалось. Вы имитировали (читай заменили) метод поиска, поэтому вычисление лямбда-выражения не выполняется, поскольку оно уже имеет определенный результат.
The while loop seem to think NamingEnumeration is empty, because of the no coverage.
The following results in 'Unnecessary stubbings detected in test class': doReturn(true,false).when(enumeration).hasMore(); and doReturn(attr).when(enumeration).next();
hasMore и next являются опечатками с вашей стороны, так как в вашем примере вызываются методы hasMoreElements и nextElement.
@Test
public void addToList() throws NamingException {
doReturn(true,false).when(enumeration).hasMoreElements();
doReturn(attr).when(enumeration).nextElement();
Assert.assertNotNull(ldapQueryDaoImpl.addToList(enumeration));
}
Вы можете проверить лямбда-выражение отдельно, пример см. ниже:
class MyMatcher implements AttributesMapper<Attributes> {
List<MyObject> list = new ArrayList<>();
public Attributes mapFromAttributes(Attributes attrs) {
NamingEnumeration<?> enumeration = attrs.get(key).getAll();
list.addAll(addToList(enumeration));
return attrs;
}
}
public void test() {
NamingEnumeration<? extends Attribute> enumeration = ...
Attribute attributeMock = mock(Attribute.class);
when(attributeMock.getAll()).thenReturn(enumeration);
Attributes attributesMock = mock(Attributes.class);
when(attributesMock.get(any(String.class)).thenReturn(attributeMock);
MyMatcher matcher = new MyMatcher();
matcher.mapFromAttributes(attr);
// assert ... matcher.list
}
Спасибо за вашу помощь. Я вижу, что ты говоришь. Теперь мне нужно только покрытие внутри лямбда-выражения. Я удалил когда в ldapTemplate.search и вместо этого попытался дать фиктивное значение для NamingEnumeration<?> enumeration = attrs.get(key).getAll();но я не могу найти правильное значение thenReturn для когда. Я пробовал это: `когда(attr.get(Mockito.anyString()).getAll()).thenReturn(enumeration);` и я получаю `метод thenReturn(NamingEnumeration<capture#1-of?> ) в типе OngoingStubbing<NamingEnumeration<capture#1-of ?>> неприменим для аргументов (NamingEnumeration<capture#3-of ?>
Вы можете переместить лямбда-выражение в другой метод и просто протестировать его отдельно. (Или просто реализуйте интерфейс AttributesMapper во внутреннем классе и проведите тесты на нем)
У меня может быть такая же проблема, потому что я не могу дать результат attr.get(Mockito.anyString()).getAll()
Я добавил некоторый свободный код (непроверенный, может не скомпилироваться) для проверки вашего лямбда-выражения. Вы должны получить идею.
На самом деле этот тест мог бы заменить оба ваших теста, так как здесь не осталось ничего, что можно было бы охватить: Осталось синтаксис поискового запроса ldap.
@Второе Спасибо за ответ. Я исправил, что не вижу другой ошибки
java.lang.ClassCastException: codegen.javax.naming.directory.Attributes$MockitoMock$1194996702 cannot be cast to java.lang.String