### Question:
ReloadNotifierImpl implements ConfijReloadNotifier<T> { @Override public <X> void registerReloadHandler(@NonNull ConfijReloadHandler<X> childReloadHandler, @NonNull Object parent, String childPath, String... childPaths) { registerReloadHandlerInternal(childReloadHandler, parent, Stream.concat(Stream.of(childPath), Stream.of(childPaths)) .toArray(String[]::new)); }  @Synchronized Optional<ReloadEvent<T>> configReloaded(@NonNull BindingResult<T> newBindingResult); @Override @Synchronized void registerRootReloadHandler(@NonNull ConfijReloadHandler<T> reloadHandler); @Override void registerReloadHandler(@NonNull ConfijReloadHandler<X> childReloadHandler, @NonNull Object parent, String childPath,
			String... childPaths); @Override void registerReloadHandler(@NonNull ConfijReloadHandler<X> reloadHandler, @NonNull X onConfigObject);  }### Answer:
@Test void customReloadHandlerTriggers() { String newValue = new Random().nextInt() + ""; AtomicBoolean handlerWasCalled = new AtomicBoolean(false); wrapper.getReloadNotifier() .registerReloadHandler(event -> { assertThat(event.getOldValue()).isEqualTo(first.x2()); assertThat(event.getNewValue()).isEqualTo(newValue); assertThat(event.getEventPath()).isEqualTo(URI.create("config:/x2")); assertThat(event.getChangedPaths()).containsExactly(URI.create("config:/x2")); handlerWasCalled.set(true); }, first.x2()); assertThat(handlerWasCalled).isFalse(); setAndReload("x2", newValue); assertThat(handlerWasCalled).isTrue(); }
@Test void noReloadHandlerOnPrimitiveAllowed() { assertThatThrownBy(() -> wrapper.getReloadNotifier() .registerReloadHandler(x -> { }, first.b() .x3())).isInstanceOf(ConfijException.class) .hasMessageContaining("primitive"); }
@Test void handlerOnChildPath() { AtomicBoolean handlerWasCalled = new AtomicBoolean(false); wrapper.getReloadNotifier() .registerReloadHandler(event -> { assertThat(event.getOldValue()).isEqualTo(3); assertThat(event.getNewValue()).isEqualTo(1337); handlerWasCalled.set(true); }, first.b(), "x3"); assertThat(handlerWasCalled).isFalse(); setAndReload("b.x3", 1337); assertThat(handlerWasCalled).isTrue(); }
@Test void unknownChildPath() { assertThatThrownBy(() -> wrapper.getReloadNotifier() .registerReloadHandler(x -> { }, first.b(), "notAChild")).isInstanceOf(ConfijException.class) .hasMessageContaining("notAChild"); }
@Test void noReloadHandlerPossibleOnDuplicate() { wrapper = ConfijBuilder.of(A.class) .bindValuesForClassWith(x -> "always me", String.class) .buildWrapper(); assertThatThrownBy(() -> wrapper.getReloadNotifier() .registerReloadHandler(x -> { }, wrapper.get() .x1())).isInstanceOf(ConfijException.class) .hasMessageContaining("always me") .hasMessageContaining("x1") .hasMessageContaining("x2"); }
@Test void noReloadHandlerPossibleOnUnknownValue() { assertThatThrownBy(() -> wrapper.getReloadNotifier() .registerReloadHandler(x -> { }, "42")).isInstanceOf(ConfijException.class) .hasMessageContaining("42"); }