0

По существу, я пытаюсь проверить действие, как если бы какой-то конкретный пользователь входил и выполнял его. У меня есть интерфейс, который я реализую на лицах, которые требуют аудита в качестве такогоТестирование модулей DAL, для которого требуется аутентифицированный пользователь

public interface IAuditableEntity 
{ 
    DateTime CreatedDate { get; set; } 

    string CreatedById{ get; set; } 

    DateTime UpdatedDate { get; set; } 

    string UpdatedById { get; set; } 
} 

В моем проекте MVC, я перезаписан функция SaveChanges() для того, чтобы автоматически заполнять в полях выше:

public override int SaveChanges() 
    { 
     var modifiedEntries = ChangeTracker.Entries() 
      .Where(x => x.Entity is IAuditableEntity 
       && (x.State == System.Data.Entity.EntityState.Added || x.State == System.Data.Entity.EntityState.Modified)); 

     foreach (var entry in modifiedEntries) 
     { 
      IAuditableEntity entity = entry.Entity as IAuditableEntity; 
      if (entity != null) 
      { 
       var identityName = (Thread.CurrentPrincipal as ClaimsPrincipal).FindFirst(ClaimTypes.NameIdentifier).Value; 

       DateTime now = DateTime.UtcNow; 

       if (entry.State == System.Data.Entity.EntityState.Added) 
       { 
        entity.CreatedById = identityName; 
        entity.CreatedDate = now; 
       } 
       else 
       { 
        base.Entry(entity).Property(x => x.CreatedById).IsModified = false; 
        base.Entry(entity).Property(x => x.CreatedDate).IsModified = false; 
       } 

       entity.UpdatedById = identityName; 
       entity.UpdatedDate = now; 
      } 
     } 

     return base.SaveChanges(); 
    } 

Это прекрасно работает во всех случаях, так как вам необходимо войти в приложение до того, как будет изменен объект IAuditableEntity. Однако я не могу понять, как это сделать.

Кажется разумным думать, что я должен назвать метод своего знака, и все должно работать оттуда. Метод мой знак в основном:

var ctx = this.Request.GetOwinContext(); 
ctx.SignIn(...) 

К сожалению, в рамках тестового проекта отсутствует объект Request. Как смоделировать Request в рамках единичного теста?

ответ

1

Просто заданное значение Thread.CurrentPrincipal с примером ClaimsPrincipal внутри Испытание модуля.

Вам не нужно устанавливать поддельные HttpRequest, так как вы используете Thread.CurrentPrincipal напрямую.

+0

Это сработало отлично. Наверное, у меня был один из моментов «духа». Однако я хочу верить, что существует лучший способ достижения желаемого результата. Кажется, это хакки ... И опять же, модульное тестирование похоже на это довольно часто. – Jeff

+0

Ничего «хакерского» нет. Проверка подлинности MVC точно совпадает с капотом (найдите источники). – Yura

+0

Лучше всего добавить в свой UnitOfWork какой-то пользовательский 'ISecurityWrapper' и вызвать его внутри' SaveChanges() '. – Yura