有没有办法在这行代码中模拟 _currencyRepository?
Is there a way I can mock _currencyRepository in this line of code?
我正在尝试使用 MOQ 框架对 class 进行单元测试。 class 中的一个 public 方法有如下一行。
看着那一行,我正试图模拟 _currencyRepository
但不知道该怎么做。考虑到它有一个像 p => new { p.Id, p.Code }
.
这样的参数
在分析代码时,它似乎是一种输出 P 的方式——我相信是匿名方法。
var currencies = await _currencyRepository.GetsAs(p => new { p.Id, p.Code }, p => p.Id == sellCurrencyId || p.Id == buyCurrencyId);
将鼠标悬停在 var 上以了解获得 returns 的类型,提示显示 IEnumerable<'a> currencies. Anonymous types: 'a is new{Guid Id, string code}
.
..而 GetAs 定义是:
public async Task<IEnumerable<TOutput>> GetsAs<TOutput>(Expression<Func<TEntity, TOutput>> projector,
Expression<Func<TEntity, bool>> spec = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>> preFilter = null,
params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] postFilters)
{
if (projector == null)
{
throw new ArgumentNullException("projector");
}
return await FindCore(true, spec, preFilter, postFilters).Select(projector).ToListAsync();
}
GetAs() 也是通用 class GenericRepository
中的 member/method - 其 class 定义为:
public class GenericRepository<TContext, TEntity> : IGenericRepository<TEntity>
where TEntity : BaseEntity
where TContext : DbContext
{
protected readonly TContext DbContext;
public GenericRepository(TContext dbContext)
{
DbContext = dbContext;
}
//followed by method definitions including GetAs
}
上面的class继承自泛型接口IGenericRepository<TEntity>
,定义为:
public interface IGenericRepository<TEntity>
where TEntity : class
{
//list of methods including GetAs
Task<IEnumerable<TOutput>> GetsAs<TOutput>(Expression<Func<TEntity, TOutput>> projector,
Expression<Func<TEntity, bool>> spec = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>> preFilter = null,
params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] postFilters);
...BaseEntity 只是一个 class 属性:
public class BaseEntity
{
public BaseEntity()
{
Id = Guid.NewGuid();
CreatedDate = DateTime.Now;
}
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
public Guid? CreatedBy { get; set; }
public Guid? UpdateddBy { get; set; }
}
我已经有了要尝试的货币列表 return,只是参数有误。不确定要使用什么参数匹配器(我知道参数匹配器是 NSubstitute 的话题。不确定它在 Moq 中是否被称为相同的)
我尝试了很多东西。其中之一如下:
var mockCurrencies3 = new[] { new { Id = buyCurrencyId, Code = "EUR" }, new { Id = sellCurrencyId, Code = "GBP" } };
MockCurrencyRepository.Setup(x => x.GetsAs(
It.IsAny<Expression<Func<Currency, (Guid, string)>>>(),
It.IsAny<Expression<Func<Currency, bool>>>(),
It.IsAny<Func<IQueryable<Currency>, IQueryable<Currency>>>()))
.Returns(Task.FromResult(mockCurrencies3.AsEnumerable()));
上面的尝试不起作用,因为 mockCurrencies3
值未在生产代码中得到 returned。我没有得到任何回报。
使用提供的信息,我能够创建一个通用方法来设置所需的行为
[TestClass]
public class MyTestClass {
[TestMethod]
public async Task Should_Mock_Generic() {
Guid buyCurrencyId = Guid.NewGuid();
Guid sellCurrencyId = Guid.NewGuid();
var mockCurrencies3 = new[] { new { Id = buyCurrencyId, Code = "EUR" }, new { Id = sellCurrencyId, Code = "GBP" } };
var mock = new Mock<IGenericRepository<Currency>>();
SetupGetAs(mock, mockCurrencies3);
var _currencyRepository = mock.Object;
var currencies = await _currencyRepository.GetsAs(p => new { p.Id, p.Code }, p => p.Id == sellCurrencyId || p.Id == buyCurrencyId);
currencies.Should().NotBeNullOrEmpty();
}
Mock<IGenericRepository<TEntity>> SetupGetAs<TEntity, TOutput>(Mock<IGenericRepository<TEntity>> mock, IEnumerable<TOutput> source)
where TEntity : class {
mock.Setup(x => x.GetsAs(
It.IsAny<Expression<Func<TEntity, TOutput>>>(),
It.IsAny<Expression<Func<TEntity, bool>>>(),
It.IsAny<Func<IQueryable<TEntity>, IQueryable<TEntity>>>())
)
.ReturnsAsync(source);
return mock;
}
}
我正在尝试使用 MOQ 框架对 class 进行单元测试。 class 中的一个 public 方法有如下一行。
看着那一行,我正试图模拟 _currencyRepository
但不知道该怎么做。考虑到它有一个像 p => new { p.Id, p.Code }
.
在分析代码时,它似乎是一种输出 P 的方式——我相信是匿名方法。
var currencies = await _currencyRepository.GetsAs(p => new { p.Id, p.Code }, p => p.Id == sellCurrencyId || p.Id == buyCurrencyId);
将鼠标悬停在 var 上以了解获得 returns 的类型,提示显示 IEnumerable<'a> currencies. Anonymous types: 'a is new{Guid Id, string code}
.
..而 GetAs 定义是:
public async Task<IEnumerable<TOutput>> GetsAs<TOutput>(Expression<Func<TEntity, TOutput>> projector,
Expression<Func<TEntity, bool>> spec = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>> preFilter = null,
params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] postFilters)
{
if (projector == null)
{
throw new ArgumentNullException("projector");
}
return await FindCore(true, spec, preFilter, postFilters).Select(projector).ToListAsync();
}
GetAs() 也是通用 class GenericRepository
中的 member/method - 其 class 定义为:
public class GenericRepository<TContext, TEntity> : IGenericRepository<TEntity>
where TEntity : BaseEntity
where TContext : DbContext
{
protected readonly TContext DbContext;
public GenericRepository(TContext dbContext)
{
DbContext = dbContext;
}
//followed by method definitions including GetAs
}
上面的class继承自泛型接口IGenericRepository<TEntity>
,定义为:
public interface IGenericRepository<TEntity>
where TEntity : class
{
//list of methods including GetAs
Task<IEnumerable<TOutput>> GetsAs<TOutput>(Expression<Func<TEntity, TOutput>> projector,
Expression<Func<TEntity, bool>> spec = null,
Func<IQueryable<TEntity>, IQueryable<TEntity>> preFilter = null,
params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] postFilters);
...BaseEntity 只是一个 class 属性:
public class BaseEntity
{
public BaseEntity()
{
Id = Guid.NewGuid();
CreatedDate = DateTime.Now;
}
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
public Guid? CreatedBy { get; set; }
public Guid? UpdateddBy { get; set; }
}
我已经有了要尝试的货币列表 return,只是参数有误。不确定要使用什么参数匹配器(我知道参数匹配器是 NSubstitute 的话题。不确定它在 Moq 中是否被称为相同的)
我尝试了很多东西。其中之一如下:
var mockCurrencies3 = new[] { new { Id = buyCurrencyId, Code = "EUR" }, new { Id = sellCurrencyId, Code = "GBP" } };
MockCurrencyRepository.Setup(x => x.GetsAs(
It.IsAny<Expression<Func<Currency, (Guid, string)>>>(),
It.IsAny<Expression<Func<Currency, bool>>>(),
It.IsAny<Func<IQueryable<Currency>, IQueryable<Currency>>>()))
.Returns(Task.FromResult(mockCurrencies3.AsEnumerable()));
上面的尝试不起作用,因为 mockCurrencies3
值未在生产代码中得到 returned。我没有得到任何回报。
使用提供的信息,我能够创建一个通用方法来设置所需的行为
[TestClass]
public class MyTestClass {
[TestMethod]
public async Task Should_Mock_Generic() {
Guid buyCurrencyId = Guid.NewGuid();
Guid sellCurrencyId = Guid.NewGuid();
var mockCurrencies3 = new[] { new { Id = buyCurrencyId, Code = "EUR" }, new { Id = sellCurrencyId, Code = "GBP" } };
var mock = new Mock<IGenericRepository<Currency>>();
SetupGetAs(mock, mockCurrencies3);
var _currencyRepository = mock.Object;
var currencies = await _currencyRepository.GetsAs(p => new { p.Id, p.Code }, p => p.Id == sellCurrencyId || p.Id == buyCurrencyId);
currencies.Should().NotBeNullOrEmpty();
}
Mock<IGenericRepository<TEntity>> SetupGetAs<TEntity, TOutput>(Mock<IGenericRepository<TEntity>> mock, IEnumerable<TOutput> source)
where TEntity : class {
mock.Setup(x => x.GetsAs(
It.IsAny<Expression<Func<TEntity, TOutput>>>(),
It.IsAny<Expression<Func<TEntity, bool>>>(),
It.IsAny<Func<IQueryable<TEntity>, IQueryable<TEntity>>>())
)
.ReturnsAsync(source);
return mock;
}
}