Skip to content

Commit 21d450b

Browse files
authored
Add ObservationContextAssert error assertions (#3267)
This change adds assertions allowing to validate the usage of Observation#error(Throwable): - `doesNotHaveError()` - `hasError()` (for any error) - `hasError(Throwable)` (for a specific error)
1 parent 5f2bd00 commit 21d450b

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationContextAssert.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,32 @@ public SELF doesNotHaveMapEntry(Object key, Object value) {
274274
return (SELF) this;
275275
}
276276

277+
public SELF doesNotHaveError() {
278+
isNotNull();
279+
Optional<Throwable> error = this.actual.getError();
280+
error.ifPresent(throwable -> failWithMessage("Observation should not have an error, found <%s>", throwable));
281+
return (SELF) this;
282+
}
283+
284+
public SELF hasError() {
285+
isNotNull();
286+
Optional<Throwable> error = this.actual.getError();
287+
if (!error.isPresent()) {
288+
failWithMessage("Observation should have an error, but none was found");
289+
}
290+
return (SELF) this;
291+
}
292+
293+
public SELF hasError(Throwable expectedError) {
294+
isNotNull();
295+
hasError();
296+
Throwable error = this.actual.getError().get();
297+
if (!error.equals(expectedError)) {
298+
failWithMessage("Observation expected to have error <%s>, but has <%s>", expectedError, error);
299+
}
300+
return (SELF) this;
301+
}
302+
277303
public ObservationContextAssertReturningThrowableAssert assertThatThrowable() {
278304
return new ObservationContextAssertReturningThrowableAssert(actual.getError().orElse(null), this);
279305
}

micrometer-observation-test/src/test/java/io/micrometer/observation/tck/ObservationContextAssertTests.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,73 @@ void should_not_throw_exception_when_map_entry_missing() {
273273
thenNoException().isThrownBy(() -> assertThat(context).doesNotHaveMapEntry("foo", "bar"));
274274
}
275275

276+
@Test
277+
void should_not_throw_when_does_not_have_error() {
278+
thenNoException().isThrownBy(() -> assertThat(context).doesNotHaveError());
279+
}
280+
281+
@Test
282+
void should_throw_when_unexpected_error() {
283+
Throwable expected = new IllegalStateException("test");
284+
285+
registry.observationConfig().observationHandler(c -> true);
286+
Observation observation = Observation.start("foo", context, registry);
287+
observation.error(expected);
288+
289+
thenThrownBy(() -> assertThat(context).doesNotHaveError())
290+
.hasMessage("Observation should not have an error, found <java.lang.IllegalStateException: test>");
291+
}
292+
293+
@Test
294+
void should_not_throw_when_has_error() {
295+
Throwable expected = new IllegalStateException("test");
296+
297+
registry.observationConfig().observationHandler(c -> true);
298+
Observation observation = Observation.start("foo", context, registry);
299+
observation.error(expected);
300+
301+
thenNoException().isThrownBy(() -> assertThat(context).hasError());
302+
}
303+
304+
@Test
305+
void should_throw_when_has_error_missing() {
306+
thenThrownBy(() -> assertThat(context).hasError())
307+
.hasMessage("Observation should have an error, but none was found");
308+
}
309+
310+
@Test
311+
void should_not_throw_when_has_specific_error() {
312+
Throwable expected = new IllegalStateException("test");
313+
314+
registry.observationConfig().observationHandler(c -> true);
315+
Observation observation = Observation.start("foo", context, registry);
316+
observation.error(expected);
317+
318+
thenNoException().isThrownBy(() -> assertThat(context).hasError(expected));
319+
}
320+
321+
@Test
322+
void should_throw_when_has_specific_error_missing() {
323+
Throwable expected = new IllegalStateException("test");
324+
325+
thenThrownBy(() -> assertThat(context).hasError(expected))
326+
.hasMessage("Observation should have an error, but none was found");
327+
}
328+
329+
@Test
330+
void should_throw_when_has_specific_error_does_not_match() {
331+
Throwable expected = new IllegalStateException("test expected");
332+
Throwable actual = new IllegalArgumentException("test actual");
333+
334+
registry.observationConfig().observationHandler(c -> true);
335+
Observation observation = Observation.start("foo", context, registry);
336+
observation.error(actual);
337+
338+
thenThrownBy(() -> assertThat(context).hasError(expected))
339+
.hasMessage("Observation expected to have error <java.lang.IllegalStateException: test expected>,"
340+
+ " but has <java.lang.IllegalArgumentException: test actual>");
341+
}
342+
276343
@Test
277344
void should_jump_to_and_back_from_throwable_assert() {
278345
context.setName("foo").setError(new RuntimeException("bar"));

0 commit comments

Comments
 (0)