Как я могу создавать и заполнять свои ложные уроки с помощью Autofixture?

В настоящее время я использую EF6 для реализации своих репозиториев внутри UnitOfWork. Я также создал макетные реализации In-Memory (MockUnitOfWork & MockRepository), чтобы я мог использовать их в модульных тестах, однако теперь мне приходится иметь дело с утомительной настройкой объектов.

Разве это не то, для чего предназначен Autofixture? Как мне получить MockUnitOfWork, который я могу использовать в своих тестах, который содержит заполненные репозитории Foo и Barr? Я использую NSubstitute для моей насмешливой среды.

IUnitOfWork

public interface IUnitOfWork
{
    void Save();
    void Commit();
    void Rollback();

    IRepository<Foo> FooRepository { get; }
    IRepository<Bar> BarRepository { get; }
}

IRepository

public interface IRepository<TEntity> where TEntity : class
{
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string         includeProperties = "");

    IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null);
    TEntity GetByID(object id);

    void Insert(TEntity entity);
    void Delete(object id);
    void Delete(TEntity entityToDelete);
    void Update(TEntity entityToUpdate);
}

2 ответа

Вы пытаетесь провести функциональное тестирование здесь, поэтому было бы разумно иметь функциональную базу данных.

EF может воссоздать и уничтожить вашу базу данных в ваших методах настройки и разрыва с помощью тестовой строки подключения. Это обеспечит реальную функциональную среду тестирования для ваших тестов, чтобы они работали против имитации реальной среды.

Пример:

        [TestFixtureSetUp]
        public static void SetupFixture() //create database
        {
            using (var context = new XEntities())
            {
                context.Setup();
            }
        }

        [TestFixtureTearDown]
        public void TearDown() //drop database
        {
            using (var context = new XEntities())
            {
                context.Database.Delete();
            }
        }

        [SetUp]
        public void Setup() //Clear entities before each test so they are independent
        {
            using (var context = new XEntities())
            {
                foreach (var tableRow in context.Table)
                {
                    context.Table.Remove(tableRow);
                }
                context.SaveChanges();
            }
        }

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

[SetUp]
public  void SetUp()
{
    // this will make AutoFixture create mocks automatically for all dependencies
    _fixture = new Fixture()
         .Customize(new AutoMoqCustomization()); 

    // whenever AutoFixture needs IUnitOfWork it will use the same  mock object
    // (something like a singleton scope in IOC container)
    _fixture.Freeze<Mock<IUnitOfWork>>(); 

    // suppose YourSystemUnderTest takes IUnitOfWork as dependency,
    // it'll get the one frozen the line above
    _sut = _fixture.Create<YourSystemUnderTest>(); 
}

[Test]
public void SomeTest()
{
    var id = _fixture.Create<object>(); // some random id
    var fooObject = _fixture.Create<Foo>(); // the object repository should return for id

    // setuping THE SAME mock object that wa passed to _sut in SetUp.
    // _fixture.Freeze<Mock part is ESSENTIAL
    // _fixture.Freeze<Mock<IUnitOfWork>>() returns the mock object, so whatever comes
    // next is Mock specific and you'll have to use NSubstitute syntax instead
    _fixture.Freeze<Mock<IUnitOfWork>>()
            .Setup(uow => uow.FooRepository.GetById(id))
            .Returns(fooObject); 

    // if this method will ask the unit of work for FooRepository.GetById(id)
    // it will get fooObject.
    var whatever = _sut.SomeMethod(id); 

    // do assertions
}

Прекрасной особенностью AutoFixture является то, что вам не нужно создавать макеты для всех зависимостей тестируемой системы. Если вы тестируете функциональность, которая использует только одну зависимость, вы просто замораживаете ее перед созданием тестируемой системы. Остальные зависимости будут автоматически проверяться.

Другие вопросы по тегам