Существуют ли способы имитации вызовов платформы сущностей, которые создают новые соединения непосредственно внутри методов

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

public bool MyMethod(int param, int param2)
{
    using (SomeEntity dBcontext = new SomeEntity())
    {
        FancyObj theobj = dBcontext.MyObjs.FirstOrDefault(l => l.ObjId == param2);
        if (theobj != null && theobj.CurrentSeason != param) //if season has changed then update
        {
            theobj .CurrentSeason = param;
            dBcontext.SaveChanges();

            return true;
        }
        return false;
    }
}

Я использую Telerik JustMock, и если я что-то не упустил, у меня не будет способа смоделировать вызов сущности, поскольку он создается непосредственно в тестируемом методе.

Является ли мое единственное решение изменить метод / класс для хранения свойства типа SomeEntity?

4 ответа

Обновление экземпляра требуемой зависимости (вместо запроса его в конструкторе) убивает тестируемость. По сути, используя new оператор, вы смешиваете заботу о реализации приложения с заботой о логике приложения.

Инъекция зависимости в помощь! Тестируемый класс должен запрашивать все, что требуется для выполнения своей работы в конструкторе, и полагаться на интерфейсы, а не на конкретные реализации. Таким образом, вы сможете предоставить поддельные реализации, чтобы сделать ваш модульный тест полностью изолированным.

Без рефакторинга вашего кода, я думаю, вам не повезет с обычными фальшивыми фреймворками, поскольку все фальшивые фреймворки зависят от virtual или interface,

Но если у вас есть Visual Studio Premium или Ultimate Edition, вы можете использовать Microsoft Fakes, которая позволяет изменять / заменять / перехватывать вызовы не виртуальных методов и свойств (работает путем изменения / внедрения кода CIL в эти 3-ий сборки, когда они загружены).

Хотя внедрение зависимостей, вероятно, является лучшим способом в долгосрочной перспективе (обычно это улучшит структуру вашего кода), существуют коммерческие решения, такие как Typemock, которые позволяют тестировать код, который нельзя протестировать обычным способом. Это немного смешанное благословение, так как вы можете стать зависимым от среды моделирования и не обязательно пожинать структурные изменения, которые могут быть поощрены модульным тестированием с более традиционными системами моделирования. Однако это должно позволить вам проверить ситуацию, которую вы описываете.

Пример с их веб-сайта показывает, как они могут получить указатель на объект, созданный в их функции Calculate. Как показано в некоторых других их примерах, этот дескриптор можно затем использовать для установки ожиданий при вызовах этой зависимости:

public static int Calculate(int a, int b)
{
   var dependency = new Dependency();
   dependency.CheckSecurity("typemock", "rules");
   return a + b;
}

[TestMethod,Isolated]
public void FakeConstructor()
{
    // Fake the Dependency constructor
    var fakeHandle = Isolate.Fake.NextInstance<dependency>();
    var result = ClassUnderTest.Calculate(1, 2);
    Assert.AreEqual(3, result);
}

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

Да, можно организовать возвращаемое значение new Выражение с использованием коммерческой версии JustMock.

var mock = Mock.Create<SomeEntity>();
Mock.Arrange(() => new SomeEntity()).Returns(mock);

С этого момента вы можете организовать макет, чтобы иметь поведение, необходимое для теста. Если вы используете EF6, то вы можете попробовать https://github.com/tailsu/Telerik.JustMock.EntityFramework, который подключается к JustMock, чтобы создавать в тестах контексты виртуальной БД в памяти.

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