Можно заморозить макет функции?

Я хочу проверить, что мой 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
}
Другие вопросы по тегам