简体   繁体   中英

C# Unit Testing - Actual: (null) Result using List in xUnit with Moq Framework

Good day,

I'm new in Unit Testing using xUnit and Moq Framework in C#.

I'm trying to test an method wherein it returns list the method is responsible for returning list of info from Queryable method inside the repository class.

Here's my test method.

[Fact]
public void SelectInfoByName_InfoHasValue_ReturnInfoSelect()
{
    var service = new Mock<ISearchInfoRepository>();

    var selectInfo = new SelectInfoService(null, service.Object);

    service.Setup(s => s.SearchInfoByName("info")).Returns(new List<Info>
    {
        new Info{ Name = "name1",InfoId = 1},
        new Info{Name = "name2",InfoId = 2}
    }.AsQueryable);

    var expectedResult = new List<Info>
    {
        new Info{Name = "name1", InfoId = 1},
        new Info{Name = "name2", InfoId = 2}
    };

    var result = selectInfo.SelectInfoByName("info").Result;

    Assert.Equal(expectedResult, result);
}

Here's my SelectInfoByName responsible for returning the list of info by name

public async Task<IEnumerable<SearchSelect>> SelectInfoByName(string info)
{
    var infoByName = searchInfoRepo.SearchInfoByName(info);

    return await infoByName.Select(info => new SearchSelect
    {
        text = info.Name,
        value = info.InfoId
    }).ToListAsync();
}

Lastly, here's my repository or storage class where it communicates with the database using EF.

// storage or repo class
public IQueryable<Info> SearchInfoByName(string info)
{
    return infoRepo.Info().Where(info => info.Name.Contains(name.Trim().ToLower()));
}

Note: Change from .AsyncState to .Result but still, the actual value is null

Thank you in advance.

You'll get an error with that particular the error message:

The source IQueryable doesn't implement IAsyncEnumerable. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.

Base on this Blog post , he used the Task.FromResult to fix the problem. So your service code should be like this:

public async Task<IEnumerable<SearchSelect>> SelectInfoByName(string info)
{
    var infoByName = searchInfoRepo.SearchInfoByName(info);

    return await Task.Result(infoByName.Select(info => new SearchSelect
    {
        text = info.Name,
        value = info.InfoId
    }).ToListAsync());
}

Then in you task method, try to use to Assert the count length rather than comparing their values.

Assert.True(expectedResult.Count(), result.Count());

When you get your result, you ask for .AsyncState.

Ask for .Result instead, to get the actual result:

var result = selectInfo.SelectInfoByName("info").Result;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM