C# fluent assertions result of check as bool - c#

I am trying to use Fluent Assertions on C# outside of test frameworks. Is there any way I could cast an FA check to bool? For example I need to achieve something like:
bool result= a.Should().Be(0);
If passes then result = true;
if fails, result = false.
Is there any way of casting or extracting a bool result from the assertion?

Fluent Assertions is designed to throw exceptions that testing frameworks catch, not to return values.
About the best you can do is to create a method that accepts an action, and that catches the exception when the action throws. In the catch you'd return false.
public bool Evaluate(Action a)
{
try
{
a();
return true;
}
catch
{
return false;
}
}
You would use it like this:
bool result = Evaluate(() => a.Should().Be(0));
This will have terrible performance in the negative case; throwing exceptions is not cheap. You might get frowns from others because, generally, exceptions shouldn't be used for flow control.
That said, this does what you want.

Related

NUnit constraint for delegate that does not throw a particular exception

I want to test that a delegate does not throw FooException, but I don't care if it throws anything else. Therefore I can't use the Nothing constraint.
The constraints model doesn't have something like this:
Assert.That(del, Throws.Not.InstanceOf<FooException>()); //can't use Not like this
Is that possible somehow?
This is slightly awkward but should do it
Assert.That(Assert.Catch(del), Is.Null.Or.Not.TypeOf<FooException>());
Personally, I prefer the two-line version
var ex = Assert.Catch(del);
Assert.That(ex, Is.Null.Or.Not.TypeOf<FooException>());
or the even clearer three-liner
var ex = Assert.Catch(del);
if (ex != null)
Assert.That(ex, Is.Not.TypeOf<FooException>());
This works because not asserting at all is the same as succeeding.
The lack of a more direct way to test this in the syntax reflects an opinion of the developers - at least at the time - that you should always know what exception you are expecting.
Looks like nunit does not provide it out of the box.
But you have some workarounds:
You may use additional assertion framework, like FluentAssertions,
which allows you to do next assertion:
del.ShouldNotThrow<FooException>();
Also you can write your own custom-constraints, like ThrowsNothingConstraint
Or you can just write custom metod
public void AssertException<T>(Action act) where T : Exception
{
try
{
act();
}
catch (T e)
{
Assert.Fail();
}
catch (Exception e)
{
Assert.Pass();
}
}

Try/Catch — How do I know what to catch in odd/complex cases?

I know why I shouldn't use open catch blocks like so:
int x = 0;
try
{
x = GetXFromSomeplaceThatCanFail();
}
catch //Possibly (Exception) or (Exception e)
{
//Ignore The Failure Because We Don't Care If It Fails
}
if (x != 0) //Yes I know I can use finally blocks to do something similar, but this is just an example case
{
//Do Things With x
}
I'm fully aware that this will "swallow" things like OutOfMemoryException, which is bad practice and can cause undetected failures/subtle errors, which are awful things.
That's why I'm going through my code and making sure there are no things like this. Normally you'd go to the documentation of whatever you're using in the try block and catch the expected exceptions, or else know that certain operations generate certain exceptions (like an IndexOutOfRangeException when accessing an array with an index, etc.).
However, there is no documentation to check in odd situations to see what exceptions may be thrown (or it's hard to find). A specific case from my own project (variable names made generic and code simplified) uses the dynamic type to grab a string field only if it exists or else fails gracefully by providing "N/A" as the result. Again, I remind you that I know that this is bad code:
string theString = "Some Old Value From Previous Run/etc.";
try
{
theString = (placeWhereValuesComeFrom as dynamic).TheString;
}
catch
{
theString = "N/A";
}
In this context, placeWhereValuesComeFrom inherits from BaseClass which doensn't (nor should it) provide TheString.
I realize that I could create an intermediate class that offers TheString and inherits from BaseClass, and then inherit from that. However, the dynamic solution was really fast to put in place and works well. Unless a better solution is put forth for my specific scenario I plan to add an intermediate class and make only the relevant classes inherit from it, then test like so:
theString = placeWhereValuesComeFrom is Subclass ? ((Subclass)placeWhereValuesComeFrom).TheString : "N/A";
However, under the assumption that I don't want to refactor for whatever reason to use an intermediate class, what should I do here? How can I discover what possible exceptions I should safely ignore in the catch block(s)? What about other similar situations where there's no real way to just "look up" what exceptions can be thrown?
The only exception you should be handling here is a runtime binding failure; when the dynamic object does not implement TheString. The type of the exception thrown is Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException.
So your code should be the following:
try
{
str = myDynamicObject.TheString;
}
catch (Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException)
{
//Binding failure
str = "N/A"
}
catch ( ... //exceptions you know TheString can throw, if any...)
{
//Handle
}
// any other exception you don't know how To handle...don't handle it

Assert that a test failure is a success

In a nunit test, can we an assert that if the test fails at a certain circumstance then it is a pass (i.e. it is expected to try and fail).
But it should pass under all other circumstances.
Thing is that the test could fall apart before it can reach it's assertions sections.
I mean something in the lines of
[TestSetup]
void init()
{
if (condition==true)
{
Assert.That(this test fails); /*any feature to do this?*/
}
}
If the test can fail and it's classed as a pass under some circumstances, it sounds a bad test. Split it out into individual tests with clear method names detailing what it's achieving.
So instead of having one test and having a conditional inside it, split it out into each scenario. That way you can have the one scenario, where it is supposed to fail under something like
// do stuff
bool success = DoStuff();
Assert.IsFalse(success);
It's a little hard to understand your question. Are you wanting Assert.Fail() to force a failure? Like so...
[TestSetup]
public void Init()
{
if (condition==true)
{
Assert.Fail();
}
}
If instead you want to check for failure instead of cause one, you should follow Arran's advice and check for a specific fact about the work you're validating - such as a method's return value.
You can also use the "Action" object to invoke the code in an action and test that action if it is an exception. Look at FluentAssertions they have lots of examples.
int number1 = 1;
int number0 = 0;
Action someAction = () => { int j = number1 / number0; };
someAction.ShouldThrow<DivideByZeroException>();

Ignoring Exceptions in xUnit.net

I have some cases where I don't care what exception is thrown (as long as some exception is thrown). Unfortunately,
Assert.Throws<Exception>(someDelegate);
doesn't pass unless exactly an instance of Exception (so not an instance of a derived class) is thrown. I know I can obtain the behavior I want with
Exception exception = Record.Exception(someDelegate);
Assert.NotNull(exception);
but it doesn't read right. Am I missing something in xUnit that has the behavior I want? Here are two tests that indicate what I mean:
[Fact]
public void Throws_exception_and_passes() {
Exception exception = Record.Exception(
() => { throw new InvalidOperationException(); }
);
Assert.NotNull(exception);
}
[Fact]
public void Throws_exception_and_fails() {
Assert.Throws<Exception>(
() => { throw new InvalidOperationException(); }
);
}
Per the documentation here:
http://xunit.codeplex.com/wikipage?title=HowToUse&referringTitle=Home
You have to specify the type of exception you want to be thrown. In general, this is good practice. You should be able to predict what scenarios a test would throw what type of exception. You should be able to design both you method and your test in a way that will allow you to predict this.
There are ways around this, like doing a try catch yourself, but you should look into changing your design a bit.
It didn't exist at the time of this question, but now one can use Assert.ThrowsAny<Exception> to test for any exception derived from Exception (and hence any exception at all), along with variants such as Assert.ThrowsAny<ArgumentException> which would test for any exception derived from ArgumentException and so on.
As you've identified if Assert.Throws<T> doesn't fit the bill, the only OOTB thing in xUnit you're left with is using Record.Exception.
As you've identified, the main way of doing a 'Assert throws anything` is to do
Assert.NotNull( Record.Exception( lambda ))
Look at it - not pretty. This is likely by design; there are very few things in xUnit.net that are by accident (as opposed to carefully considered opinionated design).
Record.Exception returns a result for a reason (and if you were using F#, you'd have to |> ignore to chuck away the value). You should always be able to Assert something about the nature of the Exception that's happening so that an actual problem in your code doesn't get ignored by chance as you change your code over time, which is the reason for all this testing stuff in the first place. Perhaps that might take the form of
var exception = Record.Exception( sut.Something );
Assert.True( typeof(SomeException).IsAssignableFrom( exception ) );
Looking at that, it's safer that an Assert.NotNull(), but still doesn't feel right. It's time to, as discussed in GOOS, listen to your tests (and in the case of an opinionated test framework, your test framework).
The biggest problem in your question is however that in a real example from a real test, there is always a way to make your interface clearer or express your expectation in another way, so the real answer is Mu.
xUnit won't stand in your way if you want to do your own Custom Assertion, something like:
public static bool Throws<T>(this Action action, bool discardExceptions = false)
where T : Exception
{
try
{
action.Invoke();
}
catch (T)
{
return true;
}
catch (Exception)
{
if (discardExceptions)
{
return false;
}
throw;
}
return false;
}
Or:
public static bool Throws(this Action action)
{
try
{
action.Invoke();
}
catch (Exception)
{
return true;
}
return false;
}
I was just looking in the xUnit.net source and here is the culprit:
private static Exception Throws(Type exceptionType, Exception exception)
{
Guard.ArgumentNotNull("exceptionType", exceptionType);
if (exception == null)
throw new ThrowsException(exceptionType);
if (!exceptionType.Equals(exception.GetType()))
throw new ThrowsException(exceptionType, exception);
return exception;
}
What would solve your problem is if this change were applied:
if(!exceptionType.Equals(exception.GetType()))
to:
if(!exception.GetType().IsAssignableTo(exceptionType))
You could possibly offer to submit a patch?
public static void SuppressException<TSut>(this TSut value, Action<TSut> action) where TSut : class
{
try
{
action.Invoke(value);
}
catch (Exception)
{
//do nothing
}
}

C# interop - validate object exists

I would like to use a COM object in my application.
How can I make sure the object is registered in the machine?
The only solution I found (also on SO) was to use a try-catch block around the initialization:
try {
Foo.Bar COM_oObject = new Foo.Bar();
} catch (Exception ee) {
// Something went wrong during init of COM object
}
Can I do it in any other way?
I feel its wrong to deal with an error by expecting it and reporting it, I would rather know I will fail and avoid it to begin with.
You are using exception handling the right way: to fail gracefully from a specific situation that you know how to recover from.
There's not a problem with using try-catch in this case, but you could at least catch more specifically : ComException.
"I feel its wrong to deal with an error by expecting it and reporting it"
Isn't it exactly the purpose of try-catch? BTW, an Exception occurs when something really bad has happened and since it is a pretty bad thing that the COM object you are referring to is not registered, therefore, an Exception is the perfect solution. And you can't handle an exception in any other way.
I think this is the right way to do it.
If you know your component's ProgId. You could try this trick
comType = Type.GetTypeFromProgID(progID,true/*throw on error*/);
If you're doing this a lot and wish you had a non-exception throwing equivalent, try:
public static class Catching<TException> where TException : Exception
{
public static bool Try<T>(Func<T> func, out T result)
{
try
{
result = func();
return true;
}
catch (TException x)
{
// log exception message (with call stacks
// and all InnerExceptions)
}
result = default(T);
return false;
}
public static T Try<T>(Func<T> func, T defaultValue)
{
T result;
if (Try(func, out result))
return result;
return defaultValue;
}
}
So now you can do this:
Foo.Bar newObj;
if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj))
{
// didn't work.
}
Or if you have a default object stored in defaultMyInterface you'd use to implement an interface if there's nothing better:
IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface,
defaultMyInterface);
You can also do this, in a completely different scenario:
int queueSize = Catching<MyParsingException>
.Try(() => Parse(optionStr, "QueueSize"), 5);
If Parse throws a MyParsingException, queueSize will default to 5, otherwise the returned value from Parse is used (or any other exception will propagate normally, which is usually what you want with an unexpected exception).
This helps to avoid breaking up the flow of the code, and also centralises your logging policy.

Categories

Resources