Unit testing xUnit测试中模拟的异步方法总是返回null
我有一个ASP.NETWebAPI 2项目,我正在尝试使用xunit和moq添加单元测试 这是我控制器中的Get方法:Unit testing xUnit测试中模拟的异步方法总是返回null,unit-testing,async-await,asp.net-web-api2,moq,xunit,Unit Testing,Async Await,Asp.net Web Api2,Moq,Xunit,我有一个ASP.NETWebAPI 2项目,我正在尝试使用xunit和moq添加单元测试 这是我控制器中的Get方法: public class SiteController : ApiController { private readonly ISite _siteSrv; public SiteController( ISite siteSrv ) { _siteSrv = siteSrv; } public async Task&
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);
}
}
公共类站点控制器:ApiController
{
私人只读访问站点srv;
公共站点控制器(iSiteSrv)
{
_siteSrv=siteSrv;
}
公共异步任务Get(int-id)
{
//正在读取当前用户登录id和用户角色[…]
//从SiteService获取数据,我尝试模拟它
var site=await\u siteSrv.Get(id,userLoginId.Value,roles);
//将其转换为模型[…]
返回Ok(型号);
}
}
和我的SiteService获取方法:
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 );
}
公共异步任务Get(int-id,long-userLoginId,string[]角色)
{
//…做一些事情
//并返回数据
return wait_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
}
}
[事实]
公共异步任务验证\u GetId\u方法\u返回\u OkResult\u ForAdmin()
{
int siteId=1;
长userLoginId=1;
字符串role=“Admin”;
//假网站
var site=新站点()
{
SiteId=1,
SiteName=“Site1”
};
//模拟站点服务
var mockSite=new Mock();
//设置异步返回假站点的Get方法
Setup(s=>s.Get(siteId,userLoginId,新字符串[]{role}))
.ReturnsAsync(现场);
//伪造HttpContext
使用(新的FakeHttpContext.FakeHttpContext())
{
//当前登录用户
HttpContext.Current.User=CurrentUserTestData.GetAccount(
userLoginId,角色);
//具有模拟SiteService的SiteController
var controller=新站点控制器(mockSite.Object);
//设置请求
controller.Request=new-HttpRequestMessage();
controller.Request.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
新的HttpConfiguration());
//调用控制器的异步Get方法
var result=await controller.Get(siteId);
//!!结果始终为空!!
Assert.NotNull(结果);//失败
}
}
知道我做错了什么吗?所以问题是参数匹配器正在查看您的参数,并试图将它们与
设置中提供的匹配。它通过使用默认相等来实现这一点,对于数组,默认相等意味着引用相等。因此,对于角色的字符串[]
,您将不匹配该参数,并且您的设置将永远不会匹配,您将得到一个空结果。更改设置以允许任何角色数组将允许匹配器成功
mockSite.Setup( s => s.Get( siteId, userLoginId, It.IsAny<string[]>() ) )
.ReturnsAsync( site );
mockSite.Setup(s=>s.Get(siteId,userLoginId,It.IsAny())
.ReturnsAsync(现场);
可能是参数匹配器与角色的字符串[]
不匹配,请尝试使用It。IsAny@JSteward就这样。非常感谢。现在我明白了。IsAny:)我用它更改了所有3个参数。它是有效的。昨天,我终于编写了一个FakeSiteService来工作,但这是一个更好的解决方案。请你写下这个作为回答,这样我就可以接受了。