Autofixture: Обвиняет Readonly для собственности, которая не ReadOnly

Созданный на 4 июн. 2013  ·  4Комментарии  ·  Источник: AutoFixture/AutoFixture

В моем доменном слое есть класс:

public class Telefone : IEntity
{
    public virtual int Id { get; protected internal set; }
    public virtual string Tipo { get; set; }
    public virtual string Numero { get; set; }
}

Идентификатор защищен внутренним. Это преднамеренно, тот, кто генерирует Id, является базой данных и должен быть ReadOnly.
Но в тестовом слое должен быть доступ к установщику этого свойства.

Итак, в моем слое домена добавлен атрибут в AssemblyInfo.cs:

[assembly: InternalsVisibleTo("MyTestLayer")]

Это позволит мне установить идентификатор на уровне тестов, но не на уровне домена!

В тестовом слое
новый Телефон (). Id = 1; // Работает!!

На уровне пользовательского интерфейса
новый Телефон (). Id = 1; // Не компилируется! Не работает!

Проблема

var pessoa = fix.Build<Pessoa>()
    .With(p => p.Nome)
    .Do((pess) =>
    {
        fix.Build<Telefone>()
            .With(p => p.Id)
            .With(p => p.Tipo)
            .With(p => p.Numero)
            .OmitAutoProperties()
            .CreateMany(10).ToList().ForEach(pess.Telefones.Add);

        fix.Build<Email>()
            .With(p => p.Id)
            .With(p => p.Tipo)
            .With(p => p.Endereco)
            .OmitAutoProperties()
            .CreateMany(10).ToList().ForEach(pess.Emails.Add);
    })
    .OmitAutoProperties()
    .Create();

Теоретически приведенный выше код должен работать, но при моем дорожном тесте возникает ошибка:

Свойство Id доступно только для чтения.

Все свойства Id s равны protected internal .

В том же файле тот же тест может делать что-то вроде:

новый Телефон (). Id = 1; // Работает!!
новый адрес электронной почты (). Id = 1; // Работает!!

question

Все 4 Комментарий

Это ясно говорит вам о том, что в вашей модели предметной области есть «нечеткая абстракция». Модель предметной области не должна разрабатываться с учетом какой-либо конкретной граничной технологии.

Эта конкретная проблема очень ясно говорит вам, что ваша модель домена _не_ повторно используется.

InternalsVisibleTo имеет никакого эффекта, потому что он разрешает доступ только к вашей тестовой библиотеке, но AutoFixture - это совершенно другая сборка. Это просто говорит вам, что _no_ другой клиент никогда не сможет повторно использовать вашу модель домена.

Лучше всего пересмотреть дизайн вашего API. Обычно я бы делал что-то вроде этого:

`` С #
открытый класс Telefone: IEntity
{
общедоступный телефон (int id)
{
this.Id = id;
}

public virtual int Id { get; private set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }

}
`` ''

Это вызвало много дискуссий в группе архитекторов, за которой я следил.
При таком подходе есть серьезная проблема:

  1. За создание идентификатора отвечает база данных, она создается только при сохранении объекта.
  2. Когда я создаю новый объект, какой идентификатор должен быть передан в конструктор? Я не могу поместить идентификатор в конструктор.
  3. Идентификатор - это последовательное целое число. Уровень репозитория - это ближайший уровень домена. Чтобы сгенерировать Id, нужно сделать что-то вроде max (id) + 1 а затем установить Id моего объекта. Но как установить Id, если он доступен только для чтения?
  4. Единственный способ установить идентификатор в свойстве ReadOnly - внутри самого класса или с помощью прокси / отражения.

Согласились, что это все _проблемы_. Все четыре из них явно указывают на то, что модель предметной области зависит от уровня персистентности и не может работать без него.

  1. Зачем базе данных присваивать идентификаторы? Единственное требование - идентификатор должен быть уникальным. Вот почему у нас есть GUID.
  2. Передайте конструктору новый экземпляр Guid.
  3. Почему идентификатор последовательный? Редко есть какие-либо архитектурные причины для того, чтобы идентификаторы были последовательными.
  4. Согласовано. Есть причина, по которой существуют модификаторы доступа.

Я понимаю проблему. Я не могу изменить тип ПК на Guid, действительно сработает.

Теперь я понимаю, что проблема не связана с AutoFixture, но если вам интересно. Я создаю образец проекта, чтобы обсудить это.

Благодарю.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

zvirja picture zvirja  ·  4Комментарии

ploeh picture ploeh  ·  7Комментарии

malylemire1 picture malylemire1  ·  7Комментарии

ploeh picture ploeh  ·  3Комментарии

zvirja picture zvirja  ·  8Комментарии