diff --git a/pkg/test/assertions/assertions.go b/pkg/test/assertions/assertions.go index c6be34e5..160c98e8 100644 --- a/pkg/test/assertions/assertions.go +++ b/pkg/test/assertions/assertions.go @@ -28,6 +28,16 @@ import ( // the Explain function. func AssertThat(t *testing.T, object client.Object, predicates ...Predicate[client.Object]) { t.Helper() + message := assertThat(object, predicates...) + if message != "" { + assert.Fail(t, "some predicates failed to match", message) + } +} + +// assertThat contains the actual logic of the AssertThat function. This is separated out into +// its own testable function because we cannot cannot capture the result of assert.Fail() in +// another test. +func assertThat(object client.Object, predicates ...Predicate[client.Object]) string { results := make([]bool, len(predicates)) failure := false for i, p := range predicates { @@ -45,8 +55,9 @@ func AssertThat(t *testing.T, object client.Object, predicates ...Predicate[clie sb.WriteString(Explain(p, object)) } } - assert.Fail(t, "some predicates failed to match", sb.String()) + return sb.String() } + return "" } // Explain produces a textual explanation for why the provided predicate didn't match. The explanation diff --git a/pkg/test/assertions/assertions_test.go b/pkg/test/assertions/assertions_test.go index f1dd2644..eba56926 100644 --- a/pkg/test/assertions/assertions_test.go +++ b/pkg/test/assertions/assertions_test.go @@ -43,6 +43,35 @@ func TestExplain(t *testing.T) { }) } +func TestAssertThat(t *testing.T) { + t.Run("positive case", func(t *testing.T) { + // given + actual := &corev1.ConfigMap{} + actual.SetName("actual") + actual.SetLabels(map[string]string{"k": "v"}) + + // when + message := assertThat(actual, Has(Name("actual")), Has(Labels(map[string]string{"k": "v"}))) + + // then + assert.Empty(t, message) + }) + + t.Run("negative case", func(t *testing.T) { + // given + actual := &corev1.ConfigMap{} + actual.SetName("actual") + actual.SetLabels(map[string]string{"k": "v"}) + + // when + message := assertThat(actual, Has(Name("expected")), Has(Labels(map[string]string{"k": "another value"}))) + + // then + assert.Contains(t, message, "predicate 'assertions.named' didn't match the object because of the following differences") + assert.Contains(t, message, "predicate 'assertions.hasLabels' didn't match the object because of the following differences") + }) +} + type predicateWithoutFixing struct{} var _ Predicate[client.Object] = (*predicateWithoutFixing)(nil)