New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type.Should().Be(Type) doesn't support open generics #954
Comments
Thanks for raising this issue. response.Should().BeAssignableTo<TType>()
response.Should().BeAssignableTo(typeof(TType)) to test that The changes related to #458 added support for open generic when using Here are my findings: First let's see how Fluent assertions behaves for non-generic types to establish a baseline. interface IInterface { }
class Base : IInterface { }
class Derived : Base { }
Derived derived = new Derived();
derived.Should().BeOfType<Derived>(); // success
derived.Should().BeAssignableTo<Base>(); // success
derived.Should().BeAssignableTo<IInterface>(); // success
derived.Should().BeOfType<Base>(); // fail
derived.Should().BeOfType<IInterface>(); // fail
Base baseClass = new Derived();
baseClass.Should().BeOfType<Derived>(); // success
baseClass.Should().BeAssignableTo<Base>(); // success
baseClass.Should().BeAssignableTo<IInterface>(); // success
baseClass.Should().BeOfType<Base>(); // fail
baseClass.Should().BeOfType<IInterface>(); // fail
IInterface interfaced = new Derived();
interfaced.Should().BeOfType<Derived>(); // success
interfaced.Should().BeAssignableTo<Base>(); // success
interfaced.Should().BeAssignableTo<IInterface>(); // success
interfaced.Should().BeOfType<Base>(); // fail
interfaced.Should().BeOfType<IInterface>(); // fail And the results for doing the same assertions on generic types, both with open and closed generic types. interface IInterface<T> { }
class Base<T> : IInterface<T> { }
class Derived<T> : Base<T> { }
Derived<int> derived2 = new Derived<int>();
derived2.Should().BeOfType<Derived<int>>(); // success
derived2.Should().BeAssignableTo<Base<int>>(); // success
derived2.Should().BeAssignableTo<IInterface<int>>(); // success
derived2.Should().BeOfType<Base<int>>(); // fail
derived2.Should().BeOfType<IInterface<int>>(); // fail
derived2.Should().BeOfType(typeof(Derived<>)); // success
derived2.Should().BeAssignableTo(typeof(Base<>)); // <-------------- now fails
derived2.Should().BeAssignableTo(typeof(IInterface<>)); // <-------- now fails
derived2.Should().BeOfType(typeof(Base<>)); // fail
derived2.Should().BeOfType(typeof(IInterface<>)); // fail
Base<int> baseClass2 = new Derived<int>();
baseClass2.Should().BeOfType<Derived<int>>(); // success
baseClass2.Should().BeAssignableTo<Base<int>>(); // success
baseClass2.Should().BeAssignableTo<IInterface<int>>(); // success
baseClass2.Should().BeOfType<Base<int>>(); // fail
baseClass2.Should().BeOfType<IInterface<int>>(); // fail
baseClass2.Should().BeOfType(typeof(Derived<>)); // success
baseClass2.Should().BeAssignableTo(typeof(Base<>)); // <-------------- now fails
baseClass2.Should().BeAssignableTo(typeof(IInterface<>)); // <-------- now fails
baseClass2.Should().BeOfType(typeof(Base<>)); // fail
baseClass2.Should().BeOfType(typeof(IInterface<>)); // fail
IInterface<int> interfaced2 = new Derived<int>();
interfaced2.Should().BeOfType<Derived<int>>(); // success
interfaced2.Should().BeAssignableTo<Base<int>>(); // success
interfaced2.Should().BeAssignableTo<IInterface<int>>(); // success
interfaced2.Should().BeOfType<Base<int>>(); // fail
interfaced2.Should().BeOfType<IInterface<int>>(); // fail
interfaced2.Should().BeOfType(typeof(Derived<>)); // success
interfaced2.Should().BeAssignableTo(typeof(Base<>)); // <-------------- now fails
interfaced2.Should().BeAssignableTo(typeof(IInterface<>)); // <-------- now fails
interfaced2.Should().BeOfType(typeof(Base<>)); // fail
interfaced2.Should().BeOfType(typeof(IInterface<>)); // fail To summarize:
If agree that Whoever takes up this task, should assure consistency in the behavior between:
Currently only |
Thanks for the quick response. I did originally try the I am assuming the changes for this would be similar to the referenced issue. |
Just looking at my test code and it appears (at least to me) that I am using the correct method. BTW: I am same person as The Pink Mile, just posting this from my mobile on the train home. |
An example of above (requires Microsoft.Extensions.DependencyInjection.Abstractions):
As i’m On train home I cannot compile and test this, but based on my observations previously, I assume this would fail. |
This sounds straightforward when the subject type is a constructed generic type of the test generic type definition. However, if the subject type is a different type which just implements or derives from the test generic type the problem it gets more complicated. |
Should BeDerivedFrom also support open generics? |
I think so. If you derive from |
What about (compare to |
Support for open generic was contributed in #955 and released with Fluent Assertions 5.5.0. |
I would expect this:
to succeed.
Instead it fails with message:
Expected type to be ICustomInterface
1, but found ICustomInterface
1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].I believe this is related to the change made for: #458
P.S. Workaround for now:
I am also using this in a few "And" constraints which forces me to do:
Which is ugly and stops me being able to add more assertions as the Subject is now the GenericTypeDefinition and not the actual Type I am validating.
The text was updated successfully, but these errors were encountered: