I use some reflection to test that all my controllers implement my BaseController.
When I test with AllBeAssignableTo it fails:
var myBaseControllerType = typeof(BaseController);
var controllers = myBaseControllerType.Assembly.Types().Where(x => x.Implements(typeof(ControllerBase)) && x != myBaseControllerType);
controllers.Should().AllBeAssignableTo<BaseController>();
Expected type to be "MyProject.Controllers.BaseController", but found "[System.RuntimeType, System.RuntimeType, System.RuntimeType, System.RuntimeType]".
However, when I use foreach, it works like a charm
var myBaseControllerType = typeof(BaseController);
var controllers = myBaseControllerType.Assembly.Types().Where(x => x.Implements(typeof(ControllerBase)) && x != myBaseControllerType);
foreach (var controller in controllers)
{
controller.Should().BeAssignableTo<BaseController>();
}
To me this is very unexpected. Can someone explain it? Or is it a bug? Not sure.
BR Matthias
There are two overloads of BeAssignableTo
ReferenceTypeAssertions.BeAssignableTo<T>() checks if the type of the subject is assignable to TTypeAssertions.BeAssignableTo<T>() checks if the subject, which is a Type is assignable to TYour second example will use TypeAssertions.BeAssignableTo(), which is why it works as expected.
AllBeAssignableTo has a single overload CollectionAssertions.AllBeAssignableTo<T>()
which can be seen as a collection edition of ReferenceTypeAssertions.BeAssignableTo<T>().
In your case:
Instead of checking { typeof(Controller1), typeof(Controller2) } it will check their types, and as typeof(Controller1).GetType() is System.RuntimeType, it will check if { System.RuntimeType, System.RuntimeType } all are assignable to BaseController
This misunderstanding seems to be recurring over and over again. Maybe we can detect misuse and throw a better description.
Maybe I'm too naive here but could we not make this AllBeAssignableTo work "as expected" instead of throwing a better description?
Fair enough. We could just fix it internally. If the collection is of type IEnumerable<RuntimeTypeInfo or IEnumerable<Type>, it does what you expext it to do.
Most helpful comment
Fair enough. We could just fix it internally. If the collection is of type
IEnumerable<RuntimeTypeInfoorIEnumerable<Type>, it does what you expext it to do.