I think I might have found a bug, but since I'm starting it might be an error by my side instead of a bug.
I'm testing a method that is marked async, and using the "Await" extension method to do so.
The issue I have is when the return type of the async method is Task<T> where T is an interface. For example, when I return a Task<IEnumerable<Car>> like for the "GetAllAsync" method of the code below:
[Subject(typeof(CarController))]
public class CarControllerTests : WithSubject<CarController>
{
Establish context = () =>
{
carService = An<ICarService>();
cars = new List<Car> { new Car() { Name = "Car 1", Id = 0, Description = "Car n1"},
new Car() { Name = "Car 2", Id = 1, Description = "Car n2"},
new Car() { Name = "Car 3", Id = 2, Description = "Car n3"},
new Car() { Name = "Car 4", Id = 4, Description = "Car n4"}};
Subject = new CarController(carService);
};
public class When_I_call_Get
{
Establish context = () => carService
.WhenToldTo(x => x.GetAllAsync())
.Return(Task.FromResult(cars.AsEnumerable()));
Because of = () => results = (List<Car>)Subject.Get().Await();
It should_call_to_get_the_list_of_cars_from_the_service = () => car.WasToldTo(x => x.GetAllAsync());
It should_send_me_the_list_of_cars = () => results.ShouldBeTheSameAs(cars);
static IEnumerable<Car> results;
} }
As you can see, I have to cast the return of the Await to List<Car> for it to work.
For this situation, it's not dramatic as I know what the concrete type of the IEnumerable would be, but there are cases where you don't know the type that would be returned, and that would make it difficult to typecast.
Another issue I have with the async methods is how to tests scenarios where I want to mock that an async method called by my subject would have an exception thrown in. I've tried the following, but I can't compile because of an ambiguity in the methods that could be called:
public class When_I_call_get_and_the_service_throws_an_exception
{
Establish context = () => carService
.WhenToldTo(x => x.GetAllAsync())
.Return(Task.Run<IEnumerable<Car>>(() => { throw new Exception(); }));
Because of = () => result = Catch.Exception(() => Subject.Get().Await());
It should_throw_an_exception = () => result.ShouldBeOfExactType<HttpResponseException>();
static Exception result;
}
Thanks
Xavier