2015-07-29 6 views
2

Я хочу проверить, действительно ли мой тип Func. Для этого я создал Mock, но я столкнулся с Exception из Autofixture. Я пробовал 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 
+0

Какие версии Moq и AutoFixture вы используете? Вы настраиваете Fixture или используете его как есть? –

+0

Я использую Autofixture 3.30.8, и я задумываюсь о нем: F = новое приспособление(). Настроить (новый AutoConfiguredMoqCustomization()); – Flodpanter

ответ

4

Такое поведение обусловлено AutoConfiguredMoqCustomization.

Когда AutoFixture настроен с помощью AutoConfiguredMoqCustomization, он передает создание экземпляров Mock специальному строителю. Этот строитель, однако, получает внутренний тип Func<int,DomainClassDummy> и создает из него макет, передавая два аргумента своего конструктора: object и IntPtr и вот где проблема.

По умолчанию строитель для делегатов создает свои экземпляры из выражения Linq Lambda Expression.

Чтобы заставить его работать, вам нужно будет создать макет самостоятельно и ввести его в AutoFixture. Инъекция - это то же самое, что и замораживание, за исключением того, что вы сами указываете экземпляр, вместо того, чтобы сообщать AutoFixture о его создании.

Вот что вы должны сделать:

var mockOfFunc = new Mock<Func<int, DomainClassDummy>>(); 
F.Inject(mockOfFunc); 
2

Объяснение, Марсио Ринальди технически правильно, но я нашел решение неудовлетворительно, так что я добавил эту способность 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 
} 
+0

Ничего себе. Это именно то, что я ищу. Я попробую это. Благодарю. – Flodpanter