question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Subset equivalency assertion

See original GitHub issue

Description

I have a container (superset) with 3 strings in it. I need to make sure that 2 strings are present in that container. Usually this comparison requires doing either a substring search or a case insensitive comparison. In either case, this involves specifying a lambda predicate for the test in the assertion.

BeSubsetOf() exists, but this requires the equals method be implemented on the objects. It would be ideal to have a similar method for testing for equivalency, especially when the subset check involves complex objects. Something like BeEquivalentSubsetOf()?

Complete minimal example reproducing the issue

Below is an example of how I execute my test today.

var ctx = TestCorrelator.GetLogEventsFromCurrentContext().ToList();
foreach (var log in expectedLogs)
{
    ctx.Should().Contain(evt => evt.MessageTemplate.Text.Contains(log));
}

Expected behavior:

What would be ideal is to do something like this:

var myStrings = new List<string> { "Hello World", "Foo Bar", "No Match" };
var expectedSubstrings = new List<string> { "Foo", "World" };
expectedSubstrings.Should().BeEquivalentSubsetOf(myStrings, (a, b) => b.Contains(a));

Using my earlier example:

expectedLogs.Should().BeEquivalentSubsetOf(TestCorrelator.GetLogEventsFromCurrentContext(),
    (log, evt) => evt.MessageTemplate.Text.Contains(log));

Versions

Using version 5.* with .NET 5

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
rcdaileycommented, May 1, 2021

For example, I want to verify that a particular method I call logs a warning. There’s other logs in there I don’t care about, like debug and informational logs. But I need to make sure one or two warnings appear in that list.

For those, you can use the overload of collection.Should().Contain() that takes a lambda expression, right?

Sorry I’ve unintentionally over-simplified my example. But what I need is to be able to specify the expected container and a lambda. Right now that option doesn’t seem to exist:

image

The current version that takes a lambda will stop after the first match. I need it to continue evaluating the lambda until the number of true returns count matches the size of the expected container.

I remember looking at HasCount() to do this, which does take a lambda, but it passes in a count not each element. So it wouldn’t work either.

Furthermore, the dataset returned is a list of some complex ref type. The test should only pass if there exists 2 objects in the list that match a specific subset, and that subset may only look at specific properties on each object (not the full object graph).

I guess you could use two calls of collection.Should().ContainEquivalentOf for that one.

Yeah that’s essentially what I’m doing now, except with a foreach instead of unrolling the loop. It matters more with larger data sets. My examples here are simplified for discussion purposes but I think you get the idea. It’s all about that extra sugar coating. I’ve started to view explicit foreach in a test as “bad” since it isn’t fluent. Maybe that’s self-imposed and wrong of me to think that way.

I’m hoping you can tell me I’m doing something wrong here.

You’re not doing anything wrong here. There are so many different ways of testing. I’m already happy that you are writing unit tests in the first place. And to be fair, I regularly run into scenarios where I wonder if there could not be a simpler way to assert some complicated scenario. But often, either I can come up with a syntax that would be incredibly hard to explain to others, or I simply can’t find anything that the compiler would be able to handle.

Thanks, I needed this reassurance. It’s definitely worth mentioning (and I should have made this clear at the start if I forgot to) that there’s no real issue here. Fluent Assertions is an amazing library that already makes things flow in a more human readable way. At the scale of problems it is solving, this is really just a nitpick.

Part of this was me feeling like I wasn’t fitting into the fluent model very well. But you’re right there’s a lot of variations. A single foreach, at the end of the day, isn’t a big deal.

I very much value and appreciate your feedback. Thank you very much.

0reactions
dennisdoomencommented, May 4, 2021

@meeple142 maybe this is what you need? It’s using a custom extension method that tries to deserialize the JSON into an anonymous type defined by an existing anonymous type and then uses FA to compare that anonymous type with itself.

Read more comments on GitHub >

github_iconTop Results From Across the Web

how to compare subset collection by value (structural ...
I want to assert if collection A is subset of collection B, using structural equality comparison (like BeEquivalentTo), using FluentAssetion ...
Read more >
Object graph comparison
Consider the class Order and its wire-transfer equivalent OrderDto (a ... You may assert the structural equality of two object graphs with Should()....
Read more >
A set is infinite iff it is equivalent to a proper subset of itself
The assertion is that a set is infinite if and only if it is equivalent to a proper subset of itself. The "if"...
Read more >
Collections
A very extensive set of extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style unit...
Read more >
9 Fluent Assertions Tricks to Save Hours of Your Testing ...
Fluent Assertions are a set of extension methods for assertions in unit testing to make the assertions more readable and easier to understand....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found