Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 849255f

Browse files
committedOct 10, 2024
Polish Update Tests
Made more robust by verifying fewer implementation details and relying more on expected outcomes Issue gh-446
1 parent 9779735 commit 849255f

File tree

1 file changed

+44
-30
lines changed

1 file changed

+44
-30
lines changed
 

‎core/src/test/java/org/springframework/ldap/core/LdapTemplateTests.java

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import javax.naming.Name;
2424
import javax.naming.NamingEnumeration;
2525
import javax.naming.NamingException;
26+
import javax.naming.directory.Attribute;
2627
import javax.naming.directory.BasicAttributes;
2728
import javax.naming.directory.DirContext;
2829
import javax.naming.directory.ModificationItem;
@@ -60,6 +61,7 @@
6061
import static org.mockito.BDDMockito.never;
6162
import static org.mockito.BDDMockito.times;
6263
import static org.mockito.BDDMockito.verify;
64+
import static org.mockito.BDDMockito.willAnswer;
6365
import static org.mockito.BDDMockito.willDoNothing;
6466
import static org.mockito.BDDMockito.willThrow;
6567

@@ -1151,56 +1153,68 @@ public void testCreateWithNoIdAvailableThrows() throws NamingException {
11511153

11521154
@Test
11531155
public void testUpdateWithIdSpecified() throws NamingException {
1154-
given(this.contextSourceMock.getReadOnlyContext()).willReturn(this.dirContextMock);
1155-
given(this.contextSourceMock.getReadWriteContext()).willReturn(this.dirContextMock);
1156+
MockDirContext dirContext = new MockDirContext();
11561157
LdapName expectedName = LdapUtils.newLdapName("ou=someOu");
1157-
1158-
ModificationItem[] expectedModificationItems = new ModificationItem[0];
1159-
DirContextOperations ctxMock = mock(DirContextOperations.class);
1160-
given(ctxMock.getDn()).willReturn(expectedName);
1161-
given(ctxMock.isUpdateMode()).willReturn(true);
1162-
given(ctxMock.getModificationItems()).willReturn(expectedModificationItems);
1163-
1158+
dirContext.bind(expectedName, TestDirContextAdapters.forUpdate(expectedName));
11641159
Object expectedObject = new Object();
1160+
Attribute added = TestNameAwareAttributes.attribute("someName", "someValue");
1161+
ModificationItem[] expectedModificationItems = { TestModificationItems.add(added) };
1162+
1163+
ArgumentCaptor<LdapDataEntry> entryCaptor = ArgumentCaptor.forClass(LdapDataEntry.class);
1164+
given(this.contextSourceMock.getReadOnlyContext()).willReturn(dirContext);
1165+
given(this.contextSourceMock.getReadWriteContext()).willReturn(dirContext);
11651166
given(this.odmMock.getId(expectedObject)).willReturn(expectedName);
11661167
given(this.odmMock.getCalculatedId(expectedObject)).willReturn(null);
1167-
1168-
given(this.dirContextMock.lookup(expectedName)).willReturn(ctxMock);
1168+
given(this.odmMock.manageClass(Object.class)).willReturn(new String[0]);
1169+
willAnswer((invocation) -> {
1170+
LdapDataEntry entry = invocation.getArgument(1);
1171+
entry.addAttributeValue(added.getID(), added.get());
1172+
return null;
1173+
}).given(this.odmMock).mapToLdapDataEntry(eq(expectedObject), entryCaptor.capture());
11691174

11701175
this.tested.update(expectedObject);
11711176

1172-
verify(this.odmMock, never()).setId(expectedObject, expectedName);
1173-
verify(this.odmMock).mapToLdapDataEntry(expectedObject, ctxMock);
1174-
verify(this.dirContextMock).modifyAttributes(expectedName, expectedModificationItems);
1175-
1176-
verify(this.dirContextMock, times(2)).close();
1177+
verify(this.odmMock, never()).setId(any(), any());
1178+
DirContextOperations operations = (DirContextOperations) entryCaptor.getValue();
1179+
assertEqualModificationItems(operations.getModificationItems(), expectedModificationItems);
1180+
assertThat(dirContext.isClosed()).isTrue();
1181+
assertThat(dirContext.getAttributes(expectedName).size()).isEqualTo(2);
11771182
}
11781183

11791184
@Test
11801185
public void testUpdateWithIdCalculated() throws NamingException {
1181-
given(this.contextSourceMock.getReadOnlyContext()).willReturn(this.dirContextMock);
1182-
given(this.contextSourceMock.getReadWriteContext()).willReturn(this.dirContextMock);
1186+
MockDirContext dirContext = new MockDirContext();
11831187
LdapName expectedName = LdapUtils.newLdapName("ou=someOu");
1184-
1185-
ModificationItem[] expectedModificationItems = new ModificationItem[0];
1186-
DirContextOperations ctxMock = mock(DirContextOperations.class);
1187-
given(ctxMock.getDn()).willReturn(expectedName);
1188-
given(ctxMock.isUpdateMode()).willReturn(true);
1189-
given(ctxMock.getModificationItems()).willReturn(expectedModificationItems);
1190-
1188+
dirContext.bind(expectedName, TestDirContextAdapters.forUpdate(expectedName));
11911189
Object expectedObject = new Object();
1190+
Attribute added = TestNameAwareAttributes.attribute("someName", "someValue");
1191+
ModificationItem[] expectedModificationItems = { TestModificationItems.add(added) };
1192+
1193+
ArgumentCaptor<DirContextOperations> entryCaptor = ArgumentCaptor.forClass(DirContextOperations.class);
1194+
given(this.contextSourceMock.getReadOnlyContext()).willReturn(dirContext);
1195+
given(this.contextSourceMock.getReadWriteContext()).willReturn(dirContext);
11921196
given(this.odmMock.getId(expectedObject)).willReturn(null);
11931197
given(this.odmMock.getCalculatedId(expectedObject)).willReturn(expectedName);
1194-
1195-
given(this.dirContextMock.lookup(expectedName)).willReturn(ctxMock);
1198+
given(this.odmMock.manageClass(Object.class)).willReturn(new String[0]);
1199+
willAnswer((invocation) -> {
1200+
LdapDataEntry entry = invocation.getArgument(1);
1201+
entry.addAttributeValue(added.getID(), added.get());
1202+
return null;
1203+
}).given(this.odmMock).mapToLdapDataEntry(eq(expectedObject), entryCaptor.capture());
11961204

11971205
this.tested.update(expectedObject);
11981206

11991207
verify(this.odmMock).setId(expectedObject, expectedName);
1200-
verify(this.odmMock).mapToLdapDataEntry(expectedObject, ctxMock);
1201-
verify(this.dirContextMock).modifyAttributes(expectedName, expectedModificationItems);
1208+
assertEqualModificationItems(entryCaptor.getValue().getModificationItems(), expectedModificationItems);
1209+
assertThat(dirContext.isClosed()).isTrue();
1210+
assertThat(dirContext.getAttributes(expectedName).size()).isEqualTo(2);
1211+
}
12021212

1203-
verify(this.dirContextMock, times(2)).close();
1213+
private static void assertEqualModificationItems(ModificationItem[] actual, ModificationItem[] expected) {
1214+
assertThat(actual).hasSize(expected.length);
1215+
for (int i = 0; i < actual.length; i++) {
1216+
TestModificationItems.assertEquals(actual[i], expected[i]);
1217+
}
12041218
}
12051219

12061220
@Test

0 commit comments

Comments
 (0)
Please sign in to comment.