Можно заморозить макет функции?
Я хочу проверить, что мой Func
Тип на самом деле выполняется. Для этого я создал Mock
, но я сталкиваюсь с Exception
из автокрепления. Я пытался Freeze
Просто Func
(без Mock
) и это работает. Может кто-нибудь объяснить, что происходит, или направить меня к правильному способу сделать это?
Сообщение об исключении:
Исключение типа 'Ploeh.AutoFixture.Kernel.IllegalRequestException' произошло в Ploeh.AutoFixture.dll, но не было обработано в коде пользователя. Дополнительная информация: Обнаружен запрос на IntPtr. Это небезопасный ресурс, который может привести к сбою процесса, если он используется, поэтому запрос отклонен. Распространенным источником запросов IntPtr являются запросы для делегатов, таких как Func или Action. В этом случае ожидаемый обходной путь - настроить (зарегистрировать или внедрить) оскорбительный тип, указав правильную стратегию создания.
Код:
public class DomainClassDummy
{
public int Id { get; set; }
}
var frozenFunc = F.Freeze<Func<int, DomainClassDummy>>(); //works
var frozenMockOfFunc = F.Freeze<Mock<Func<int,DomainClassDummy>>>(); //fails
2 ответа
Такое поведение связано с AutoConfiguredMoqCustomization
,
Когда AutoFixture настроен с AutoConfiguredMoqCustomization
, он передает создание экземпляров Mock специальному строителю. Этот строитель, однако, получает внутренний тип Func<int,DomainClassDummy>
и создает из него макет, передавая два аргумента своего конструктора: object
а также IntPtr
и вот в чем проблема.
Конструктор по умолчанию для делегатов создает его экземпляры из лямбда-выражения Linq.
Чтобы заставить его работать, вам нужно создать макет самостоятельно и добавить его в AutoFixture. Внедрение это то же самое, что и замораживание, за исключением того, что вы сами указываете экземпляр, вместо того чтобы сказать AutoFixture создать его для вас.
Вот что вы должны сделать:
var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
F.Inject(mockOfFunc);
Объяснение, данное Марсио Ринальди, является технически правильным, но я нашел решение неудовлетворительным, поэтому я добавил эту возможность в https://www.n uget.org/packages/AutoFixture.AutoMoq/3.31.1.
Этот тест сейчас проходит:
[Fact]
public void FixtureCanFreezeUsableMockOfFunc()
{
// Fixture setup
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var expected = fixture.Create<Uri>();
var mockOfFunc = fixture.Freeze<Mock<Func<Guid, decimal, Uri>>>();
mockOfFunc
.Setup(f => f(It.IsAny<Guid>(), 1337m))
.Returns(expected);
// Exercise system
var actual = mockOfFunc.Object(Guid.NewGuid(), 1337m);
// Verify outcome
Assert.Equal(expected, actual);
// Teardown
}