2

I'm new to testing with Moq, so I'm confused a bit regarding ReturnsAsync. Here is my test method, where I'm expecting ReturnsAsync should receive type that will be returned by method defined in Setup. Am I right?

But seemed ReturnsAsync should have the other signature - it's looking for Func delegate.

[TestClass]
public class TourObjectControllerTest
{
    [TestMethod]
    public async Task GetTourObjects()
    {
        var mockService = new Mock<ITourObjectService>(MockBehavior.Default);
        mockService.Setup(x => x.GetAll()).ReturnsAsync(new Task<IEnumerable<TourObjectDTO>>);
        var controller = new TourObjectController(mockService.Object);
        var result = await controller.Get();
        Assert.IsNotNull(result);
        Assert.AreSame(typeof(TourObjectViewModel), result);
    }
}

Method under test:

public async Task<IEnumerable<TourObjectViewModel>> Get()
{
    IEnumerable<TourObjectViewModel> viewmodel = null;
    try
    {
        var tourobjects = await _tos.GetAll();
        viewmodel = Mapper.Map<IEnumerable<TourObjectViewModel>>(tourobjects);
    }
    catch (Exception ex)
    {
        Log.ErrorFormat("Method:{0} <br/> Error: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex);
    }
    return viewmodel;
}
2
  • What does Intellisense say? (I assume you're working in VS.)
    – Kenneth K.
    Commented Dec 8, 2016 at 14:53
  • @KennethK., it say that Task<IEnumerable<..>> is not assignable to type Func<IEnurable<...>> Commented Dec 8, 2016 at 14:57

2 Answers 2

1

Pass an actual result.

Assuming ITourObjectService.GetAll() returns Task<IEnumerable<TourObjectDTO>>

eg

[TestClass]
public class TourObjectControllerTest
{
    [TestMethod]
    public async Task GetTourObjects()
    {
        var fakeData = new List<TourObjectDTO>() {
            new TourObjectDTO { ... }
        };
        var mockService = new Mock<ITourObjectService>(MockBehavior.Default);
        mockService.Setup(x => x.GetAll()).ReturnsAsync(fakeData);
        var controller = new TourObjectController(mockService.Object);
        var result = await controller.Get();
        Assert.IsNotNull(result);
        Assert.IsTry(typeof(IEnumerable<TourObjectViewModel>).IsAssignableFrom(result.GetType());
    }
}
7
  • Please correct me if I'm wrong, Moq generate random data of type IEnumerable<TourObjectViewModel>? Commented Dec 8, 2016 at 15:02
  • 1
    No it does not. not without some extension or plugin
    – Nkosi
    Commented Dec 8, 2016 at 15:02
  • Well, so how this simulate repository/service behaviour? Commented Dec 8, 2016 at 15:04
  • You are mocking the service and providing some fake data to return when the mocked member is called.
    – Nkosi
    Commented Dec 8, 2016 at 15:05
  • Test failed even with actual result - Error in Assert.IsNotNull() Commented Dec 8, 2016 at 15:09
1

ReturnsAsync() should take a return value as the paramter instead of Task<TReurnValue>. For example, next 2 lines of code are equal (by behavior):

mockService.Setup(x => x.GetAll()).ReturnsAsync(new List<TourObjectDTO>());
mockService.Setup(x => x.GetAll()).Returns(Task.FromResult(new List<TourObjectDTO>()));

You need to replace new List<TourObjectDTO>() with your test data which you want to retrieve in the test from the mock. For example, you can create just few test values:

var testData = new [] { new TourObjectDTO(1, "test1"), new TourObjectDTO(2, "test2") };
mockService.Setup(x => x.GetAll()).ReturnsAsync(testData);

or create fake data generator if needed.

Note that ReturnsAsync() is only available for methods that return a Task<T>. For methods that return only a Task, .Returns(Task.FromResult(default(object))) can be used.

2
  • Yes, method GetAll return Task<IEnumerable<OfSomeClass>> Commented Dec 8, 2016 at 15:00
  • @andrey.shedko ok then just pass an expected value for this method as an parameter of ReturnsAsync or use Returns with Task.Result as in the code above. Commented Dec 8, 2016 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.