https://kotlinlang.org logo
#strikt
Title
p

Pihentagy

06/27/2023, 4:01 PM
Hi, new to strikt, I guess there must be a more elegant way to say:
Copy code
expectThat(result) {
            get { statusCode }.isEqualTo(HttpStatus.OK)
            get { body }.isNotNull().and {
                get { elements }.and {
                    hasSize(1)
                    expectThat(first().subject) {
                        get { coordinates }.isEqualTo(listOf(coord))
                        get { networkType }.isEqualTo(NetworkType.SWITCH)
                    }
                }
            }
        }
s

Saharath Kleips

06/27/2023, 5:48 PM
I’m not a pro, but it looks like you have basically the gist of it, but there are a couple of comments. • The StriKT docs suggest preferring to use `get` with function references: So
get(HttpResponse::statusCode).isEqualTo(…)
over
get { statusCode }
. In my experience needing the lambda version is an edge case. • You probably should be using
that(first().subject)
rather than
expectThat
but to me it’s probably another
get
? • StriKT also has functions for asserting collections: So I’d probably write some variation of
get(Subject::coordinates).containsExactlyInAnyOrder(coord)
I think in general, StriKT lets you write these assertions in a way that makes the output of a test result become immediately clear and specific as to what failed. So, I wouldn’t say any of it is necessarily wrong (the assertions still ultimately work) but reading the result of a failure could be improved.
r

robfletcher

06/27/2023, 9:08 PM
A couple of things you could do to simplify:
Copy code
expectThat(result) {
  get { statusCode }.isEqualTo(HttpStatus.OK)
  get { body }
    .isNotNull().get { elements }
    .hasSize(1)
    .withFirst {
      get { coordinates }.isEqualTo(listOf(coord))
      get { networkType }.isEqualTo(NetworkType.SWITCH)
    }
}
You shouldn’t nest an
expect
method inside another one. Unfortunately there’s not really a way for me to prevent that, but it can create unpredictable results. The
and
method is for grouping multiple assertions and there are a couple of places where you only really have one thing inside of it, so it’s not necessary.
also, the earlier point about function references is valid. They perform a bit better (due to the way the failure message is generated with just a closure) but that’s only really a concern with very large numbers of tests, e.g. when doing generative tests
e

Eric

06/27/2023, 9:15 PM
What about
single()
instead of
hasSize(1).withFirst { ... }
?
r

robfletcher

06/27/2023, 9:15 PM
oh, I think I missed navigating to
.subject
there, but hopefully you get the idea
yeah,
single
is basically
hasSize(1).first()
. I went for
withFirst
in order to group the 2 assertions on that element
p

Pihentagy

06/28/2023, 7:33 AM
Cool, thanks, learned a lot about strikt about these comments
I find get with closure readable and I don't mind the little performance loss (yet).
What about changing
Copy code
.hasSize(1).withFirst() { ... }
to
Copy code
.single().and() { ... }
Shouldn't be a single version with blocks, so that I can write:
Copy code
.single() { ... }
r

robfletcher

06/28/2023, 5:43 PM
we could add a
withSingle { }
yeah
(which would effectively just be
.single().and { }
as you say)
p

Pihentagy

06/28/2023, 8:40 PM
Nice, thanks!
3 Views