fluentassertions: Ability for custom failure messages?

I just want to show some debug information in my failure message if the assertion fails…

I came to this library because XUnit dropped support for this, and i heard this library was much better in this regard… which it is for the default messages… but it seems you can still not do custom ones?

for instance I have an xunit theory right now

[Theory, MemberData(nameof(_GetTestWaferData))]
public void WaferInfoFinder_OverValidInput_Succeeds(WaferInfoFinderInput validInput) {
  var containerManager = new CommonTestContainerManager();
  var waferInfoFinder = containerManager.WaferInfoFinder;
  var waferInfo = waferInfoFinder.GetWaferInfo(validInput);

  waferInfo.IsDummy.Should().BeTrue(_DebugString(validInput));

  waferInfo.Warning.Should().BeNullOrEmpty();
}

and i just want to display the full information of the input if it fails, so I don’t have to try to figure out which input failed…

but the message i get is “Message: Expected True because LOT_ID: GA05-11161 WAFER_ID: F, but found False.”

which makes no sense in English and I’m not sure how to reword it because I can’t seem to touch the word “Because” unless I’m missing something?

Is there a better way to do this? Or is this library just for showing the reason why you put the assert and not for showing debug information? 😦

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 34 (12 by maintainers)

Most upvoted comments

so let’s say you have a service that returns status and error object. You want to check if status is successful and you want to print the error object.

Currently I get something like: Expected object to be Succeeded because {becauseMessage}, but found Failed.

Adding anything not related to the reason why it should be succeeded makes the part after the comma sound weird:

Ex:

Expected object to be Succeeded because creating the service with one node should be possible. Error from service was: Out of memory, but found Failed.

Would be better to have it for example:

Expected object to be Succeeded because {becauseMessage}, but found Failed.
{ExtraMessage}

so that we can add the message we want:

Ex:

Expected object to be Succeeded because creating the service with one node should be possible, but found Failed.
Error from service was: Out of memory.

As for implementation, you can add an extension .AddMessage(string message) to add the extra message we want to show.

@alexcyoung, Nope, I gave example here

So how about this, when the message ends with ., instead, it is written in the next line:

Expected value to be 10, but found 5.
some reason.

The example you wrote would fail if for example you have this:

eatApple.Should().BeTrue("because my Dr. said I should do")

which would translate to:

Expected eatApple to be true because my Dr, but found false.
said I should do

@faeriedust you could also use the following construct:

using (new AssertionScope(_DebugString(validInput) + "IsDummy"))
{
   waferInfo.IsDummy.Should().BeTrue();
}

This should give you something like expected LOT_ID: GA05-11161 WAFER_ID: F IsDummy to be true, but found false.

@sskfny I agree x 1000 and then some. I cannot comprehend why the sentence structure is output as it currently is. I was expecting something like you were expecting too. You have a valid question and expectation. But it hasn’t changed in two years+, so I wouldn’t expect it to change now. Fluentassertions make the code a lot more readable, but not the output error message. I don’t understand when then sentence structure, “Expected boolean not to be False because Something failed arguments wrong, but found False.”, would/could ever be a considered normal sentence structure. But again, really good for making code a lot easier to read.

@fractalocity Thank you for sharing your insights 😜

I don’t where your frustrations are coming from exactly, but that “because” option is, well, optional. I only use it occasionally when I think it adds clarity to the outcome. No need to be dogmatic about it.

I won’t look very fluent unfortunately

From params documentation

No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.

waferInfo.ShouldBeEquivalentTo(new WaferInfo
{
    IsDummy = true,
   Warning = ""
}, options => options.Including(x => x.IsDummy).Including(x => x.Warning));

Or

waferInfo.ShouldBeEquivalentTo(new
{
    IsDummy = true,
   Warning = ""
});

Or just write the original assertion as:

waferInfo.IsDummy.Should().BeTrue($"because {_DebugString(validInput)} is a dummy");