This is a migrated thread and some comments may be shown as answers.

Invalid return type when testing Async methods

4 Answers 201 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Vikas
Top achievements
Rank 1
Vikas asked on 04 Jan 2016, 07:26 PM

I have 2 classes Parent and a Child class, child class inherits from parent.

Class under test has an async method that returns Task<parent>.

I am arranging the Test method in my unit test, Mock.Arrange(() => viewmodel.Test()).Returns(Task.FromResult(new child()));

I am getting this error, Why is it having a problem in casting a child to its parenttype

ErrorCS1503Argument 1: cannot convert from 'System.Threading.Tasks.Task<ViewModels.child>' to 'System.Threading.Tasks.Task<ViewModels.parent>'ViewModels.Tests

public class viewmodel{

public async Task<parent> Test()
        {
            await Task.Delay(100);
            return null;              
        }
    }

    public class parent
    {

    }

    public class child : parent
    {

    }

4 Answers, 1 is accepted

Sort by
0
Vikas
Top achievements
Rank 1
answered on 04 Jan 2016, 07:35 PM

If i change the arrange to this then it does not give compile time error:

Mock.Arrange(() => viewmodel.Test()).Returns(Task.FromResult<parent>(new child()));

But then i get invalid cast exception in the the code under test.

this line of code in the class under test throws can not cast from Threading.Task.Task<parent> to Threading.Task.Task<child>

child a  = await viewModel.Test() as child;

 

 

0
Vikas
Top achievements
Rank 1
answered on 04 Jan 2016, 09:48 PM
It is working if i remove any expectations from the arrange like occurs(1). Does just mock supports expectations for async methods?
0
Stefan
Telerik team
answered on 05 Jan 2016, 08:06 AM
Hi Vikas,

Task<child> is not convertible to Task<parent>, because in .NET only interfaces and delegates, but not classes, may have convariant generic parameters. Explicitly specifying the type parameter of FromResult<T> is the correct way.

This compiles:
Task<parent> task = Task.FromResult<parent>(new child());
This does not:
Task<parent> task = Task.FromResult(new child());

I tried the following code and I didn't get a type cast exception:
public class parent
{
}
 
public class child : parent
{
}
 
public interface ITest
{
    Task<parent> Test();
}
 
[TestMethod]
public async Task Test()
{
    var mock = Mock.Create<ITest>();
    Mock.Arrange(() => mock.Test())
        .Returns(Task.FromResult<parent>(new child()))
        .OccursOnce();
 
    child o = await mock.Test() as child;
}
A more complete example would help examine the issue.

Regards,
Stefan
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Vikas
Top achievements
Rank 1
answered on 21 Jan 2016, 03:09 PM
This works, Thanks
Tags
General Discussions
Asked by
Vikas
Top achievements
Rank 1
Answers by
Vikas
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or