我有2个项目,Data和Data.test,我使用ef核心和.net核心,对于Data项目我有这样的ExpenseDb:
public class ExpenseDb: DbContext
{
private IConfigurationRoot _config;
public ExpenseDb(DbContextOptions<ExpenseDb> options, IConfigurationRoot config) : base(options)
{
_config = config;
}
public DbSet<Account> Accounts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer(_config["Data:ConnectionString"]);
}
}
我有一个像这样的帐户存储库:
private ExpenseDb _db;
public AccountRepository(ExpenseDb db)
{
_db = db;
}
public IEnumerable<Account> All(Guid userId)
{
return (_db.Accounts.AsNoTracking().Where(a => a.UserId == userId).ToList());
}
我使用ms IOC进行注入依赖,如下所示:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json");
_config = builder.Build();
}
IConfigurationRoot _config;
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(_config);
services.AddDbContext<ExpenseDb>(ServiceLifetime.Scoped);
}
这些都在我的Data项目中,对于Data.Test,我想测试All方法,我意识到我必须模拟我的ExpenseDb,所以我从Nuget Package获得Moq,现在我有这样的测试类:
[TestClass]
public class AccountRepositoryTest
{
private readonly Mock<ExpenseDb> _dbMock = new Mock<ExpenseDb>();
private readonly AccountRepository _repo;
public AccountRepositoryTest()
{
_repo = new AccountRepository(_dbMock.Object);
}
[TestMethod]
public void AllForInvalidUser()
{
var fakeaccount = new Account() { Name="cat2",OpenDate=DateTime.Now,StartBalance=100};
Mock < DbSet < Account >> acMock = DbSetMock.Create(fakeaccount);
var results = _repo.All(Guid.Parse("cf15c6c9-f688-47ee-892e-297e530be053"));
Assert.IsNotNull(results);
}
}
显然我的测试失败了,因为我必须以某种方式将配置和选项传递给我的ExpenseDb,但我不知道怎么办?!
我搜索过,我发现所有答案都说“你必须有一个接口为你的服务”,但我不想创建一个不必要的界面。