Roll your own assertion (and do something fun with the methods)? - c#

I couldn't think of a way to describe what I'm trying to do for the question title--which may be why I couldn't just Google it. Any help either titling or Googling would be hot.
Here's the code I'm looking for:
Assert.That(true == false);
...or...
Assert.That(true == false).Else<ArgumentException>();
At this point, I can make the second one work or I can make the first one work. (The first one throws a very general "AssertionFailedException", which I would like to keep as the default in the event that the .Else() part isn't supplied.
Is there a way I can make these both work?

The problem is, by the time That has been evaluated by the runtime, it doesn't know there is an additional method call (Else) to make. Frameworks like NUnit use a different syntax that avoids this problem:
Assert.That(someValue, Is.Not.EqualTo(someOtherValue))
You construct a constraint, pass it to Assert.That, then NUnit does the actual validation and exception throwing.
You could introduce a syntax like this (using NUnit again as an example):
Assert.That(someValue, Is.Not.EqualTo(someOtherValue).Else<ArgumentException>());
That way, configuring what exception to throw if the assertion fails is simply part of the constraint configuration.

Related

How to check if object does NOT contain an item in NUnit?

Is there a way to check if an object does NOT contain an item in NUnit? The NUnit.Framework.Assert.Contains() method checks if an item is contained, but I am looking for the opposite here. A lot of methods have a negative counterpart (like Assert.NotNull(), Assert.AreNotEqual() and Assert.DoesNotThrow()), but Contains() Seems to be lacking such an opposite method.
The only way I found is checking it manually using Assert.That(), but that is a little bit clunky and doesn't read as well.
Assert.That(!result.Dependencies.Contains<string>("tableName"));
I believe these should work:
Assert.That(result.Dependencies, Does.Not.Contain("tableName"));
Assert.That(result.Dependencies, Has.None.EqualTo("tableName"));
In general, the framework has not added new "Classic" assertions for some years. DoesNotContain would be easy to implement, so you can always ask the project for it if you prefer the older syntax.
#Commenters... The problem with Assert.That(bool condition) is that it doesn't give a very good error message, so I can understand why #Axel doesn't want to use it. Of course, it can be used with an error message specified, but that's more typing. :-)

Using FakeItEasy, is it possible to create a dummy object of a type that takes generic type parameters

I have the following test:
[Fact]
public void StartProgram_CallsZoneProgramStart()
{
var zone = A.Fake<Zone>();
zone.StartProgram();
A.CallTo(() => zone.ZoneProgram.Start(null, A.Dummy<ActionBlock<InterruptInfo>>())).MustHaveHappened(Repeated.Exactly.Once);
}
It's creating a dummy of type ActionBlock<InterruptInfo> which is being passed into the MustHaveHappened call. zone.StartProgram definitely calles the zone.ZoneProgram.Start method, but this call is not seen by FakeItEasy. It returns the following error message:
Assertion failed for the following call:
ZoneLighting.ZoneProgramNS.ZoneProgram.Start(<NULL>, ActionBlock\`1 Id=1)
Expected to find it exactly once but found it #0 times among the calls:
1: ZoneLighting.ZoneProgramNS.ZoneProgram.Start(inputStartingValues: Faked ZoneLighting.ZoneProgramNS.InputStartingValues, interruptQueue: ActionBlock`1 Id=2)
2: ZoneLighting.ZoneProgramNS.ZoneProgram.Start(inputStartingValues: <NULL>, interruptQueue: ActionBlock`1 Id=2)
As can be seen from the error message, the ID on the ActionBlocks being compared are different (1 and 2), which is why it's not able to see that the call is made. My question is, why is the ID of the dummied ActionBlock = 1? I thought being a dummy object, it shouldn't have any concrete details in it like ID etc. Is this because generic types cannot be dummied?
I saw something similar here: https://github.com/FakeItEasy/FakeItEasy/issues/402
But I wasn't able to figure out if that's talking about the same thing or not. Any help would be greatly appreciated.
I am not familiar with ActionBlocks, so am not sure where they get their Id values from, but I think I can shed some light on what's going on in your test.
First, I think you're confused about what a Dummy is. If so, don't feel bad. They can be a little confusing. From the Dummy documentation, a Dummy is
Dummy is an object that FakeItEasy can provide when an object of a certain type is required, but the actual behavior of the object is not important.
They are mostly used by FakeItEasy itself when it needs to create an object to feed to class constructors (we'll see more about that later), or when it needs to return a non-fakeable object from a method or property. It's rare for end users to have to create them.
A Dummy is an actual object (it has to be—otherwise, how could we do anything with it?). It has to have whatever concrete details in it that its type has (in this case, ActionBlock<InterruptInfo>). There are no restrictions against Dummying generic types.
Looking at the docs for how a Dummy is made, we can see that since ActionBlock<InterruptInfo> probably doesn't have a custom IDummyDefinition available (do you have one?), and it's not a Task, and it's not fakeable (because the class is sealed), then the Dummy is made by invoking one of the ActionBlock constructors, with Dummies being made to satifsy each of the arguments.
I guess that ActionBlocks have IDs. How they're assigned, I have no idea, but if they're a good ID, then it looks like we have two different ActionBlock<InterruptInfo>s: one provided in zone.StartProgram, and the Dummy made in the test.
The ActionBlocks documentation suggests that it doesn't override Equals, so a reference comparison will be performed, and the two ActionBlocks (the Dummy and the one used in the production code) don't match. This is why FakeItEasy doesn't recognize the call.
If you were just trying to see if any call to zone.ZoneProgram.Start was made with the first argument null and the second argument some ActionBlock, I think you might've meant to use:
A.CallTo(() => zone.ZoneProgram.Start(null, A<ActionBlock<InterruptInfo>>.Ignored))
.MustHaveHappened(Repeated.Exactly.Once);
(Ignored can also be shortened to _. Read more about ignoring argument values if you're so inclined.)
That may get you past your immediate problem, although I have concerns about two things:
It looks like zone.ZoneProgram.Start is being called twice, not "Exactly.Once", but I'm sure you'll be able to deal with this, and
In general, faking the object under test is considered to be an anti-pattern. Typically one supplies fake dependencies to the production code under test. I'm not saying it won't work, but sometimes it can lead to confusion. Still, it may be a problem for another day, after the current question has been resolved.
I hope that helps a little.
Oh, and you asked about Issue 402. That issue is about giving users more power when defining customization classes that will control how dummies are created. Unless you've made a class extending IDummyDefinition or DummyDefinition, it's probably not relevant at this point.

Using Code Contracts to ensure collection remains unchanged

I'm trying to implement the post-condition of a method. I want to guarantee that it doesn't change a particular part of the internal state (I fixed a bug, as it used to do so. For refression purposed, I'm adding the post-condition in code). My best attempt was as follows:
Contract.Ensures(PropertyA.Collection.Count == Contract.OldValue(PropertyA.Collection).Count);
Contract.Ensures(Contract.ForAll(0, PropertyA.Collection.Count, index => this.PropertyA.Collection[index].Equals(Contract.OldValue(this.PropertyA.Collection)[index])));
The problem with this code is that Contract.OldValue(PropertyA.Collection) caused a null reference exception in the second line. In the manual of Code Contracts in section 11.8 (http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf) is stated that this particular Contract.ForAll ought to work with Contract.OldValue, but another overload doesn't.
Is there another way how I can perform the check that the items in PropertyA.Collection haven't changed in value, nor have been reordered in some way?
It is unclear from your question, but I expect that PropertyA.Collection and PropertyB.Collection are reference types.
One gotcha with Contracts.OldValue() and reference types is, that Contracts.OldValue() doesn't save the old object pointed at, but rather the pointer itself.
For this reason, your first contract will always be true, since you effectively compare the value to itself.
The proper way to write it would be
Contract.Ensures(PropertyA.Collection.Count == Contract.OldValue(PropertyA.Collection.Count));
I'm not sure why your second contract fails.
Normally when trying to compare a collection before and after a method call, you need to save the collection as an enumerable:
Contract.OldValue(PropertyA.Collection.ToList())
// or
Contract.OldValue(PropertyA.Collection.ToArray())
This will evaluate the expression and save the reverence to the list/array, which can then be indexed.
Sorry to answer so late, but there are not too much activity in code contracts.
I think there are two sides of the problem:
1) To ensure the condition, as you ask, I think that can be done using a [Pure] function to do it, and calling this function in the Contract.Ensures
2) Unfortunately it only solves the problem locally. Note this situation:
1- Call a function which ensures a condition on de collection
2- Call a function which ensures no change in the collection
3- Call a function which has as precondition the condition ensured in (1)
The [Pure] function in (2) to ensure no change is done in the collection does not allow CodeContracts to infer that the postcondition in (1) ensures the precondition in (3).
I think that CodeContracts should offer a functionality to ensure no change in an object, but taking the object as the "deep object"; something that lets you write something like
proposal code
Contract.Ensures(PureArgument(PropertyA.Collection))
As the functionality PureArgument should be part of CodeContracts, it could be an attribute:
proposal code
[PureArgument(PropertyA.Collection)]
Note that CodeContracts could check that the PureArgument property is fulfilled, as it can do a deep compare; really complex and expensive to check (it needs a deep copy), but it can be done. But the checking won't be the question, but to check the code to ensure that the parameter is not deep changed, which is not always possible.
Anyway, I'm sure that a feature like that will be great, even without checking it fullfils the assertion, and without checking the code to ensure the parameter is not changed (which is more interesting than checking the assertion is fullfiled, but impossible to cover at all).
Turning back to the question, a solution to ensure that a collection doesn't change could be to use new ReadOnlyCollection(PropertyA.Collection) as parameter, instead of using PropertyA, but it is a change in the code.

Best exception for an invalid generic type argument

I'm currently writing some code for UnconstrainedMelody which has generic methods to do with enums.
Now, I have a static class with a bunch of methods which are only meant to be used with "flags" enums. I can't add this as a constraint... so it's possible that they'll be called with other enum types too. In that case I'd like to throw an exception, but I'm not sure which one to throw.
Just to make this concrete, if I have something like this:
// Returns a value with all bits set by any values
public static T GetBitMask<T>() where T : struct, IEnumConstraint
{
if (!IsFlags<T>()) // This method doesn't throw
{
throw new ???
}
// Normal work here
}
What's the best exception to throw? ArgumentException sounds logical, but it's a type argument rather than a normal argument, which could easily confuse things. Should I introduce my own TypeArgumentException class? Use InvalidOperationException? NotSupportedException? Anything else?
I'd rather not create my own exception for this unless it's clearly the right thing to do.
NotSupportedException sounds like it plainly fits, but the documentation clearly states that it should be used for a different purpose. From the MSDN class remarks:
There are methods that are not
supported in the base class, with the
expectation that these methods will be
implemented in the derived classes
instead. The derived class might
implement only a subset of the methods
from the base class, and throw
NotSupportedException for the
unsupported methods.
Of course, there's a way in which NotSupportedException is obviously good enough, especially given its common-sense meaning. Having said that, I'm not sure if it's just right.
Given the purpose of Unconstrained Melody ...
There are various useful things that can be done with generic
methods/classes where there's a type constraint of "T : enum" or "T :
delegate" - but unfortunately, those are prohibited in C#.
This utility library works around the prohibitions using ildasm/ilasm ...
... it seems like a new Exception might be in order despite the high burden of proof we justly have to meet before creating custom Exceptions. Something like InvalidTypeParameterException might be useful throughout the library (or maybe not - this is surely an edge case, right?).
Will clients need to be able to distinguish this from BCL Exceptions? When might a client accidentally call this using a vanilla enum? How would you answer the questions posed by the accepted answer to What factors should be taken into consideration when writing a custom exception class?
I would avoid NotSupportedException. This exception is used in the framework where a method is not implemented and there is a property indicating that this type of operation is not supported. It doesn't fit here
Shameless self Reference: http://blogs.msdn.com/jaredpar/archive/2008/12/12/notimplementedexception-vs-notsupportedexception.aspx
I think InvalidOperationException is the most appropriate exception you could throw here.
Generic programming should not throw at runtime for invalid type parameters. It should not compile, you should have a compile time enforcement. I don't know what IsFlag<T>() contains, but perhaps you can turn this into a compile time enforcement, like trying to create a type that is only possible to create with 'flags'. Perhaps a traits class can help.
Update
If you must throw, I'd vote for InvalidOperationException. The reasoning is that generic types have parameters and errors related to (method) parameters are centered around the ArgumentException hierarchy. However, the recommendation on ArgumentException states that
if the failure does not involve the
arguments themselves, then
InvalidOperationException should be
used.
There is at least one leap of faith in there, that method parameters recommendations are also to be applied to generic parameters, but there isn't anything better in the SystemException hierachy imho.
I would use NotSupportedException as that is what you are saying. Other enums than the specific ones are not supported. This would of course be stated more clearly in the exception message.
I'd go with NotSupportedException. While ArgumentException looks fine, it's really expected when an argument passed to a method is unacceptable. A type argument is a defining characteristic for the actual method you want to call, not a real "argument." InvalidOperationException should be thrown when the operation you're performing can be valid in some cases but for the particular situation, it's unacceptable.
NotSupportedException is thrown when an operation is inherently unsupported. For instance, when implementing an interface where a particular member doesn't make sense for a class. This looks like a similar situation.
Apparently, Microsoft uses ArgumentException for that, as demonstrated on example of Expression.Lambda<>, Enum.TryParse<> or Marshal.GetDelegateForFunctionPointer<> in Exceptions section. I couldn't find any example indicating otherwise, either (despite searching local reference source for TDelegate and TEnum).
So, I think it's safe to assume that at least in Microsoft code it's a common practice to use ArgumentException for invalid generic type arguments aside from basic variable ones. Given that the exception description in docs doesn't discriminate between those, it's not too much of a stretch, either.
Hopefully it decides the question things once and for all.
Id go with NotSupportedExpcetion.
Throwing a custom made exception should always be done in any case where it is questionable. A custom exception will always work, regardless of the API users needs. The developer could catch either exception type if he does not care, but if the developer needs special handling he will be SOL.
I'm always wary of writing custom exceptions, purely on the grounds that they aren't always documented clearly and cause confusion if not named correctly.
In this case I would throw an ArgumentException for the flags check failure. It's all down to preference really. Some coding standards I've seen go as far as to define which types of exceptions should be thrown in scenarios like this.
If the user was trying to pass in something which wasn't an enum then I would throw an InvalidOperationException.
Edit:
The others raise an interesting point that this is not supported. My only concern with a NotSupportedException is that generally those are the exceptions that get thrown when "dark matter" has been introduced to the system, or to put it another way, "This method must go into the system on this interface, but we won't turn it on until version 2.4"
I've also seen NotSupportedExceptions be thrown as a licensing exception "you're running the free version of this software, this function is not supported".
Edit 2:
Another possible one:
System.ComponentModel.InvalidEnumArgumentException
The exception thrown when using invalid arguments that are enumerators.
I'd also vote for InvalidOperationException. I did an (incomplete) flowchart on .NET exception throwing guidelines based on Framework Design Guidelines 2nd Ed. awhile back if anyone's interested.
How about inheriting from NotSupportedException. While I agree with #Mehrdad that it makes the most sense, I hear your point that it doesn't seem to fit perfectly. So inherit from NotSupportedException, and that way people coding against your API can still catch a NotSupportedException.

Which is more fluent - longer or shorter syntax?

I am trying to create my first fluent interface and I was just wondering what other poeple thought was more fluent and which one they would prefer to use?
Check.Field().Named("est").WithValueOf("sdsd").IsNotNull()
Check.Field("est").WithValueOf("sdsd").IsNotNull()
Check.Field("est").WithValue("sdsd").IsNotNull()
Cheers
Anthony
Last one definitely:
Check.Field("est").WithValue("sdsd").IsNotNull()
I concur:
Check.Field("est").WithValue("sdsd").IsNotNull()
As short as possible, while still making sense.
Avoid noise words like .as. .of. .and. .in. unless they add contextual meaning. I've seen fluent interfaces that do this, and it adds nothing useful except more typing and more hoops for the application to jump through when it executes.
Another option might be:
Check.Field("est").IsNotNull("sdsd")
Something like LINQ's FirstOrDefault called with a predicate instead of filtering and then calling FirstOrDefault.
What is Check? I suspect it's not needed at all. I understand what you're trying to do, but remember that the expression you're trying to build will still likely end up in an if statement. With that in mind, think about how "if check X" reads. Not too well, imho. Additionally, what does the 'Field' function have to do to resolve that name? Do you have that somewhere else that you could present in a nicer way (perhaps an extension method on some base type?)
Or, to mimic some of the collections, use of Item property:
Check["est"].WithValue("sdsd").IsNotNull()
Some might also say you should just use .IsNull() and negate the whole expression, like this, but that's a "six -vs- half a dozen" thing:
!Check["est"].WithValue("sdsd").IsNull()

Categories