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 );
我有一个 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 );