xUnit-Test returns 中的模拟异步方法始终为 null

Mocked Async Method in xUnit-Test returns always null

我有一个 ASP.NET WebAPI 2 项目,我正在尝试使用 xunit 和 moq 添加单元测试。

这是我控制器中的获取方法:

public class SiteController : ApiController
{
    private readonly ISite _siteSrv;

    public SiteController( ISite siteSrv )
    {
        _siteSrv = siteSrv;
    }

    public async Task<IHttpActionResult> Get( int id )
    {
        //reading current user login id and user roles [...]

        // getting data from SiteService, which I try to mock
        var site = await _siteSrv.Get( id, userLoginId.Value, roles );

        //converting it into a model [...]

        return Ok(model);
    }
}

还有我的 SiteService Get 方法:

public async Task<Site> Get( int id, long userLoginId, string[] roles )
{
    //...doing some stuff
    // and returning the data
    return await _context.Sites
        .AsNoTracking()
        .FirstOrDefaultAsync( s => s.SiteId == id );
}

这是我的测试方法:

[Fact]
public async Task Verify_GetId_Method_Returns_OkResult_ForAdmin()
{
    int siteId = 1;
    long userLoginId = 1;
    string role = "Admin";

    // fake site
    var site = new Site()
    {
        SiteId = 1,
        SiteName = "Site1"
    };

    // mocking the SiteService
    var mockSite = new Mock<ISite>();
    // setting up the Get-Method returning the fake site asynchronously
    mockSite.Setup( s => s.Get( siteId, userLoginId, new string[] { role } ) )
        .ReturnsAsync( site );

    // faking HttpContext
    using ( new FakeHttpContext.FakeHttpContext() )
    {
        // current logged in user
        HttpContext.Current.User = CurrentUserTestData.GetAccount( 
            userLoginId, role );

        // the SiteController with the mocked SiteService
        var controller = new SiteController( mockSite.Object );
        // setting Request
        controller.Request = new HttpRequestMessage();
        controller.Request.Properties.Add( 
            HttpPropertyKeys.HttpConfigurationKey,
            new HttpConfiguration() );

        // calling the async Get method of the controller
        var result = await controller.Get( siteId );
        // !! result is always NULL !!

        Assert.NotNull( result ); // FAIL
    }
}

知道我做错了什么吗?

所以问题是参数匹配器正在查看您的参数并尝试将它们与 Setup 中提供的内容相匹配。它通过使用默认相等性来做到这一点,对于数组意味着引用相等性。因此,对于您的 string[] 个角色,您将不会匹配该参数,并且您的 Setup 将永远不会匹配,您将得到一个空结果。更改您的设置以允许任何角色数组将使匹配器成功。

mockSite.Setup( s => s.Get( siteId, userLoginId, It.IsAny<string[]>() ) )
    .ReturnsAsync( site );