BeEquivalentTo doesn't work with Anonymous Methods - fluent-assertions

I have an xunit test using FA 4.19.3. I have recently upgraded to 5.3.0 without too many issues, except for some Object graph comparisons.
Old test:
var result = await MyClass.GetResultAsync();
result.ShouldBeEquivalentTo(new
{
StatusCode = 200,
Exception = (Exception)null
}, options => options.Excluding(o => o.Context));
But because the expectation is an anonymous method the Excluding errors with:
'IMemberInfo' does not contain a definition for 'Context' and no
extension method 'Context' accepting a first argument of type
'IMemberInfo' could be found (are you missing a using directive or an
assembly reference?)
I even tried defining the generic:
result.Should().BeEquivalentTo<MyResult>(
but this did not help.
How can I continue to use the anon method as I have many tests using this method.

Actually, we introduced some pretty big breaking changes in 5.0 just to make it possible to compare against an anonymous type. The Excluding method is there to exclude properties from the expectation. Since your expectation doesn't have an Context object, FA will complain about that. Check out https://www.continuousimprover.com/2018/02/fluent-assertions-50-best-unit-test.html#redefining-equivalency

Related

How to use `Which` in FluentAssertions?

I'm using fluent assertions and I have this test:
result.Should().NotBeNull();
result.Link.Should().Equals("https://someinvoiceurl.com");
which works fine but when I try this
result.Should().NotBeNull().Which.Link.Equals("https://someinvoiceurl.com");
I got this error
'AndConstraint<ObjectAssertions>' does not contain a definition for 'Which' and no accessible extension method 'Which' accepting a first argument of type 'AndConstraint<ObjectAssertions>' could be found (are you missing a using directive or an assembly reference?)
What I'm doing wrong?
The problem here is that .NotBeNull() is not generic (it is an extension on ObjectAssertions rather than GenericObjectAssertions), so it can't chain the type information to later calls.
I think this is a flaw in the library design, personally, but it is easily worked around by substituting .NotBeNull() with .BeOfType<T>() as so:
result.Should().BeOfType<ThingWithLink>() // assertion fails if `result` is null
.Which.Link.Should().Be("https://someinvoiceurl.com");
Of course, if you assert on your ThingWithLink type a lot, it could be worth writing a custom assertion so that you can be "more fluent":
result.Should().BeOfType<ThingWithLink>()
.And.HaveLink("https://someinvoiceurl.com");
If you need something more ad-hoc, you can always just use .BeEquivalentTo() to do structural comparison:
result.Should().NotBeNull()
.And.BeEquivalentTo(new { Link = "https://someinvoiceurl.com" }); // ignores all members on `result` except for `result.Link`

Reuse the description of an existing Error when creating a new Error

I have the following code in Rust, which does not compile, but shows the intent of what I'd like to do.
pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
use self::byteorder::{BigEndian, ReadBytesExt};
use self::core::error::Error;
match cursor.read_u16::<BigEndian>() {
Err(byteorder::Error::Io(error)) => Err(error),
Err(error) =>
Err(io::Error::new(io::ErrorKind::Other, error.description(),
None)),
Ok(value) => Ok(Ack { block_number: value })
}
}
Essentially, I want to take the error description of an error returned by the byteorder library and use it to create the description of an error I'll pass back to the user of my library. This fails with packets.rs:166:58: 166:63 error:errordoes not live long enough, and I understand why.
The byteorder library solves this issue by wrapping an std::io::Result in the byteorder::Error::Io constructor. However, I don't want to take this route because I'd have to define my own error type that wraps either an std::io::Error or a byteorder::Error. It seems to me that my users shouldn't know or care that I use the byteorder library, and it shouldn't be part of my interface.
I'm a Rust newbie and don't yet know the idioms and best practices of the language and design. What are my options for dealing with this?
Your problem is in fact in that io::Error::new()'s second parameter is &'static str, while byteorder::Error::description() returns a &'a str where 'a is lifetime of the error object itself which is less than 'static. Hence you can't use it for io::Error's description.
The simplest fix would be moving byteorder::Error description to detail field of io::Error:
Err(error) =>
Err(io::Error::new(
io::ErrorKind::Other,
"byteorder error",
Some(error.description().to_string())
)),
However, you should seriously consider making a custom wrapper error type which encapsulates all "downstream" errors. With properly written FromError instances you should be able to write something like
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
instead of your whole match. Custom error wrappers will also help you when your program grows and more "downstream" error sources appear - you could just add new enum variants and/or FromError implementations to support these new errors.
I cannot test your code so I can't be sure. Isn't the ref keyword enough?
Err(byteorder::Error::Io(ref error)) => Err(error),

Workflow won't compile

I'm getting the following error when trying to execute my custom build definition (containing only 1 custom CodeActivity):
Exception Message: Expression Activity type 'CSharpReference`1' requires compilation in order to run. Please ensure that the workflow has been compiled. (type NotSupportedException)
I've tried multiple suggested answers to this error, but none of them are applicable to my activity. My CodeActivity only has a couple of methods that search through directories for specific files, and then returns a delimited string containing the file names.
I don't use any WorkflowInvoker or any DynamicActivities. For what reason would I keep getting this error?
Thanks
I had the same error on an assignment step.
System.NotSupportedException: Expression Activity type 'CSharpValue`1' requires compilation in order to run.
Please ensure that the workflow has been compiled.
The resolution was to remove the carriage returns from statement.
For example this works:
new Foo() { Bar = new Bar() { MyProp1 = "123" } }
This does not:
new Foo()
{
Bar = new Bar()
{
MyProp1 = "123"
}
}
I decided not to work in a clean xaml file, but instead to use the Default Template provided by TFS. The Default template ran my activities without errors.
I was able to fix this solution as well by using the Default Template provided by TFS, clearing all of their activities, and adding the custom activities and arguments in my original custom template.
However, more insight in to this issue, it seems to be caused by the fact that custom template use C# expressions to handle the arguments. Where as the default template is set up to use VB Expressions for it's arguments.
In my case, the language didn't matter because the values were simply strings.

Dart serialization error: Invalid reference

I have a wrapped Serialization class from the serialization package in my class MySerialization. In the constroctor of MySerialization, I add a bunch of rules. Consumer classes have seperate instances of the wrapper MySerialization class to (de)serialize objects.
This setup, with a seperate instance of MySerialization in consumer classes throws an error in the Reference class constructor:
Reference(this.parent, this.ruleNumber, this.objectNumber) {
if (ruleNumber == null || objectNumber == null) {
throw new SerializationException("Invalid Reference");
}
if (parent.rules.length < ruleNumber) {
throw new SerializationException("Invalid Reference"); // <---- here
}
}
thus spawnes error in the console
Breaking on exception: SerializationException(Invalid Reference)
This means a rule cannot be found which is referenced. The starnge thing howver is, that I have the same rules applied in all Serialization instances through the MySerialization wrapper.
I tried serializing with only one instance of MySerialization. This does not spawn the error. When I debug in DartEditor, I get the <optimized out> message in the debugger window.
I have CustomRule subclasses rules defined. The behavior does not change when I enable/disabled these CustomRules
What cuases the invalid reference, and how to solve & workaround this error?
Dart Editor version 1.5.3.release (STABLE)
Dart SDK version 1.5.3
It's difficult to answer without a little more detail on your setup. However, I'm going to guess that you're using the default setup in which it will automatically generate instances of BasicRule when it encounters a class that it doesn't know about, and those are added to the list of rules. Your other instance doesn't know about those, so it fails.
You can try examining (or just printing) the list of rules in your original serialization after it has written out the objects and see if this is the case.
To fix this, you would need to write rules for the other objects that are being serialized and weren't in your original list. Or you could use the "selfDescribing" option, in which case it will send the rules that were used along with the original. But that won't work if you have hard-coded custom rules which it can't serialize.

Can I get the parameters used in an expectation in Rhino Mocks?

I am setting up an expectation for a call to a method that builds and executes a query. I would like to interrogate the properties of the parameter used. Is this possible
using (mocks.Record())
{
Expect.Call(connection.Retrieve(SOMETHING_HERE)).Return(returnedDatay);
}
The bit I am after is the "SOMETHING HERE" bit.
(This is my first time using Rhino mocks)
You can set up constraints on your parameters and on the properties of the parameters. The following code sets up a constraint on a property named MyProperty on your connection object. The mock expects the MyProperty to be 42. Notice, that null is passed as the parameter since it is ignored.
Expect
.Call(connection.Retrieve(null))
.IgnoreArguments()
.Constraints(Property.Value("MyProperty", 42))
.Return(returnedData);
I am writing this from memory so it may not be absolutely correct.
UPDATE:
Rhino Mocks version 3.5 introduces a new extension method GetArgumentsForCallsMadeOn that lets you inspect the parameters passed to the mocked objects:
http://kashfarooq.wordpress.com/2009/01/10/rhino-mocks-and-getargumentsforcallsmadeon/