我有一个基于EF Code First
使用MSSQL server
的项目。在我的一个存储库中,我使用PredicateBuilder
动态构建查询。要在每次代码中发生更改时手动测试所有可能的结果,都非常耗时。
出于这个原因,我想通过单元测试来实现自动化。我正考虑使用sql compact
进行单元测试,MSSQL server
进行生产。但是如何为sql compact
服务器启用迁移?
这是dbContext类:
public partial class ApplicationDbContext :
IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
public ApplicationDbContext() : base("name=DefaultConnection") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());
base.OnModelCreating(modelBuilder);
}
}
存储库:
public class FilterRepository : IFilterRepository
{
private ApplicationDbContext _dbContext;
public FilterRepository(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
DbInterception.Add(new CommandInterceptor());
}
public IEnumerable<Person> GetPersons(Filter filter)
{
try
{
var persons = PredicateBuilder.False<Person>();
_dbContext.Configuration.AutoDetectChangesEnabled = false;
var result = _dbContext.Persons
.AsNoTracking()
.Where(persons)
.OrderBy(x => x.Name)
.Skip(filter.Skip)
.Take(10)
.ToList();
_dbContext.Configuration.AutoDetectChangesEnabled = true;
return result;
}
catch (Exception ex)
{
}
}
}
答案 0 :(得分:2)
好的,所以切换到另一个数据库进行测试是(imo)一个坏主意。
以下是一些适合您的术语,可以帮助您更好地组织测试。
单元测试用于测试您的业务功能,通常您只是为此模拟数据,因为您要测试域类中输入(数据)的变化,而不是它们来自何处。
集成测试用于测试业务域层与服务层的交互方式(您的数据层是服务层),我还会将查询的正确性视为集成测试,以便运行它们。 / p>
因此,在您的情况下,不要混淆事物,并可能添加因2个数据库的工作方式不同而导致的意外行为。如果您正在测试您的业务功能,请为此模拟您的数据。它的启动速度更快,您将进行测试,正是您想要测试的内容。
通过集成测试,您正在测试您与服务层的交互是否正确,在这种情况下,您的测试并未真正测试业务逻辑是否正常工作,应该在单元测试中进行测试;测试您的查询是否为其谓词返回正确的数据,以及要保留的任何数据是否正确保留。此外,任何正在进行的交易都按预期工作。场景的端到端测试也是一种有效的集成测试。
您绝对需要在与生产相同的数据库平台上执行此操作,不要期望SQL Compact和SQL Server的行为方式相同。
编辑...评论。
因此,模拟存储库调用的正常方式是使用依赖注入,您不必这样做,但它更简单,也是最佳实践。
我们的想法是,在您使用数据的域类中,首先从DI容器中获取存储库或查询类,该容器注入构造函数或从DI容器中提取
// in your domain class you would have something like...
var repo = container.Get<IRepository>();
var myList = repo.GetMyObjects(predcate);
因此,使用Moq,您现在可以简单地模拟该调用
//Where you do your container registration..
var repo = Mock<IRepository>
repo.Setup( o => o.GetMyObject(predecate)).Returns( (predecate) => <your dummy list>));
container.Register(repo.Object);
// Then later on your business domain object gets the dummy repo instead.
注意这是伪代码,每使用DI和Mocking框架会有所不同。