New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for property based assertion #3908
Comments
We do have Kudos for putting the effort into writing a great issue 💯 |
That's exactly it and a much cleaner API than what I suggested! Thank you very much!! 😃 It's a bit hard to find though (it was at least for me). I think something that useful deserves at least to be mentioned here https://kotest.io/docs/assertions/core-matchers.html. I would create a specific table with the name of "Properties" for it and place it right after "General". Unless this usage is not that common as I think it is. I will definitely use it very often! Thanks again! |
OK, I think I've just found a a bug in This is how I could reproduce it: Wihtout data class Person(val firstName: String, val lastName: String, val age: Int)
val expected = Person("James", "Bond", 56)
val actual = Person("John", "Bond", 52)
actual::firstName shouldHaveValue expected.firstName
actual::lastName shouldHaveValue expected.lastName
actual::age shouldHaveValue expected.age Prints:
With data class Person(val firstName: String, val lastName: String, val age: Int)
val expected = Person("James", "Bond", 56)
val actual = Person("John", "Bond", 52)
withClue("Assertion for Person failed") {
assertSoftly {
actual::firstName shouldHaveValue expected.firstName
actual::lastName shouldHaveValue expected.lastName
actual::age shouldHaveValue expected.age
}
} Prints:
As you can see the version with the soft block is missing the message I had a look at the code and the problem seems to be in the |
Do you want to contribute a fix? Sounds like you're pretty on top of it already 😄 |
I was actually considering it while I was writing 😄. I'll give it a try. |
Ok, I've prepared a fix now but I'm not able to push it or create a pull request. Do you have to give me permission first?
|
For open source projects, you need to fork the repo, and then you push the branch to your fork. Then github will prompt you to make a PR back from your fork to this repo. |
This PR resolves kotest#3908 * implementation now only returns matcher instead of calling shouldBe and catching exception, so that it also works with assertSoftly * extension function is now also mentioned in the core documentation * added missing package to properties.kt
Fix information printed by KProperty0<T>.shouldHaveValue (kotest#3908)
This PR resolves #3908 * implementation now only returns matcher instead of calling shouldBe and catching exception, so that it also works with assertSoftly * extension function is now also mentioned in the core documentation * added missing package to properties.kt Co-authored-by: Sam <sam@sksamuel.com>
Very often it's required to assert multiple properties of a given object and if the assertion fails, you have no clue on which property the assertion failed, unless of course you use the nice "Clues" feature of Kotest 😄. Writing clues for each property however feels a bit verbose and clunky and it's not type safe if the property is renamed for example.
Here an example to show the problem:
Of course, one could simply assert the whole object (especially if it's a data class) like so:
actual shouldBe expected
But what if I have many properties in my class and I don't want to assert all properties because not all are relevant for my test case. Plus, what if I have many properties and only one fails? I would get a huge string generated for each object and it wouldn't be that easy to find which property is different..
So, I tried to find something in the API that could help me with this problem but couldn't find anything, so I ended up creating the following extension function:
As you may have guessed from the code and KDoc comment, this allows me to write the code above as follows and yield the exact same result:
To make it really nice for bigger classes, one could do something like that:
withClue("Assertion for Person failed") { assertSoftly { actual::firstName shouldGet expected::firstName actual::lastName shouldGet expected::lastName actual::age shouldGet expected::age } }
Which brings me to further ideas like having an API where I can pass the actual and expected objects and a list of properties and it generates the clue with the class name like above.
Anyway, this is not necessarily a feature request but just wanted to share this use-case with this forum to check if there is a bigger demand for something like this and let you guys consider adding such concepts to the API in future releases. I'm happy to help with the coding part if required.
The text was updated successfully, but these errors were encountered: