4

Je ne peux pas vérifier et tester ma base de données dans les fournisseurs de mémoire. par exemple, je définir ces propriétés Required:Validation d'entités à l'aide d'annotations de données ou d'une API fluide dans EF 7.0 (en mémoire)

public abstract class Log 
{ 
    #region Properties 
    public Guid Id { get; set; } 
    [Required] 
    public string ClientIp { get; set; } 
    [Required] 
    public string Application { get; set; } 
    [Required] 
    public string Host { get; set; } 
    [Required] 
    public string Path { get; set; } 
    [Required] 
    public string Method { get; set; } 
    [Required] 
    public string User { get; set; } 
    [Required] 
    public string Date { get; set; } 
    #endregion 
} 

et ceci est mon DBContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUsers, Role, Guid>, IUnitOfWork 
{ 
    private readonly IConfigurationRoot _configuration; 

    public ApplicationDbContext(IConfigurationRoot configuration) 
    { 
     _configuration = configuration; 
    } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    { 
     var useInMemoryDatabase = _configuration[key: "UseInMemoryDatabase"].Equals(value: "true", 
      comparisonType: StringComparison.OrdinalIgnoreCase); 
     if (useInMemoryDatabase) 
      optionsBuilder.UseInMemoryDatabase(); 
     else 
      optionsBuilder.UseSqlServer(
       connectionString: _configuration[key: "ConnectionStrings:ApplicationDbContextConnection"] 
       , sqlServerOptionsAction: serverDbContextOptionsBuilder => 
       { 
        var minutes = (int) TimeSpan.FromMinutes(3).TotalSeconds; 
        serverDbContextOptionsBuilder.CommandTimeout(commandTimeout: minutes); 
       }); 
    } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Log>() 
      .HasKey(c => c.Id); 
     modelBuilder.Entity<Log>() 
      .HasDiscriminator<int>(name: "Type") 
      .HasValue<LogRequest>(value: Convert.ToInt32(value: LogLevel.Information)) 
      .HasValue<LogError>(value: Convert.ToInt32(value: LogLevel.Error)); 


    } 

Et ceci est mon test unitaire:

[TestClass] 
public class LogRepositoryTest 
{ 


    private readonly IServiceProvider _serviceProvider; 
    public LogRepositoryTest() 
    { 
     var services = new ServiceCollection(); 
     services.AddScoped<IUnitOfWork, ApplicationDbContext>(); 
     services.AddScoped<ILogRepository, LogRepository>(); 
     services.AddSingleton(provider => new ConfigurationBuilder() 
      .AddInMemoryCollection(initialData: new[] 
      { 
       new KeyValuePair<string, string>(key: "UseInMemoryDatabase", value: "true"), 

      }) 
      .Build()); 
     services.AddEntityFrameworkInMemoryDatabase().AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped); 
     _serviceProvider = services.BuildServiceProvider(); 
    } 
    [TestMethod] 
    public async Task Verify_SaveRequestLog() 
    { 
     using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) 
     { 
      using (var context = serviceScope.ServiceProvider.GetRequiredService<IUnitOfWork>()) 
      { 
       context.Set<Log>().Add(new LogRequest()); 
       var result =await context.SaveAllChangesAsync(); 
       Assert.AreEqual(1, result); 
      } 

     } 
    } 

Mais la méthode de test unitaire toujours renvoie 1 et passe, pendant ce temps l'objet vide de LogRequest ne doit rien sauvegarder dans la base de données! Comment puis-je déterminer des propriétés non nulles pour le test unitaire? En fait, comment puis-je appliquer le test unitaire pour refléter les politiques de validation?

Mise à jour:

Sur la base de cette linke: Entity Framework Core Issues

que j'ai demandé, je suis arrivé ce répondre:

EF Core ne fait pas de validation des entités au-delà est nécessaire pour la cohérence interne. La validation est quelque chose qui peut être fait dans EF, mais l'expérience montre que ce n'est pas quelque chose qui est utile à beaucoup de développeurs car il ne peut généralement pas remplacer la validation côté client ou la validation de la base de données. être fait plus efficacement.

En allant au-delà de EF vers la base de données, la base de données en mémoire ne valide pas actuellement la nullité (c'est-à-dire la nécessité) lors de l'enregistrement des valeurs de propriété . Je vais laisser ce numéro ouvert pour que nous puissions discuter en tant qu'équipe de s'il y a quelque chose que nous devrions ajouter.

De même, si l'intention est de tester avec une base de données en mémoire en tant qu'approximation pour une base de données relationnelle, vous pouvez utiliser pour utiliser SQLite en mode en mémoire. Voir https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/index pour plus d'informations.

Répondre

1

Sur la base de cette linke: Entity Framework Core Issues

que j'ai demandé, j'ai eu ma réponse:

class MyContext : DbContext 
{ 
public override int SaveChanges() 
{ 
    var entities = from e in ChangeTracker.Entries() 
        where e.State == EntityState.Added 
         || e.State == EntityState.Modified 
        select e.Entity; 
    foreach (var entity in entities) 
    { 
     var validationContext = new ValidationContext(entity); 
     Validator.ValidateObject(entity, validationContext); 
    } 

    return base.SaveChanges(); 
} 
} 
+0

cette approche ne fonctionne que pour des annotations de données, pas si vous avez utilisé l'API couramment – phifi