I have the following test
[Fact]
public void GivenAResultWithAnExceptionWeGetAStackTrace()
{
InterstingStackTrace(3)
.Match(
ok: v => Assert.True(false),
error: e => Assert.NotNull(e.StackTrace));
}
I am aware of the discussion in #2027, however I would like to ask the xunit authors, how I should proceed to have an idiomatic solution. I do not propose to have Assert.Fail, but an idiomatic possibility to write tests with pattern matching without resorting to hacks like above.
The problem with the hack is: should I write Assert.True(false), Assert.False(true) or throw NotImplementedException()? Those are all ok, but ultimatly fail in semantic terms. And I don't want to support my own test library just for this really basic functionality.
I see your problem, you want the people to write real tests, where they express their assertions correctly. But currently I cannot do that. Of course I could make my own xUnit, but I don't want to. And I want that people writing Functional Style have a simple option to write pattern matching code correctly. I like xUnit, exactly because you know what you do, and I love the CodeChecker.
But I do not really want a Fail semantic anway, I want to express, that this code will not be called, and in FP style I have a lot of tests which look exactly as the above.
So, if the semantic is the problem and not the actual functionality, may we could give it a better semantic meaning, I have a few options how we could call it:
Assert::Unmatched()
Very narrow meaning, specific for functional style pattern matching. Not very appealing to OO programmers. Maybe not easy to understand for broad audiences. This also means it probably would not be abused as a general Fail.
Assert::NotCalled()
We can easily express that this part of the expression should not be called. This could be easily used by OO and procedural style programming as well as FP style. Good semantics, easy to understand. It is obviously closer to Fail then the Unmatched, but I think the potential for abuse is not worse than Assert::True(false).
Assert::Unreachable()
Same idea as not called, it is easy to understand and very explicit about the code semantics. It uses the language of warning CS0162 which should be understandable by most C# programmers. IMHO very similar to NotCalled().
I am open to suggestions for better names, but I really would like to express tests in a semantic way without using inapropriate tools.
[Fact]
public void GivenAResultWithAnExceptionWeGetAStackTrace()
{
InterstingStackTrace(3)
.Match(
ok: v => throw new XunitException(),
error: e => Assert.NotNull(e.StackTrace));
}
Actually that is very close to a Fail(), but that way I could at least give a nice error message:
v => throw new XunitException("invalid pattern match")
I'm actually swayed by the functional argument, doubly so because of switch expressions in C# 8. That's a good enough reason to add Assert.Fail.
Most helpful comment
I'm actually swayed by the functional argument, doubly so because of switch expressions in C# 8. That's a good enough reason to add Assert.Fail.