2015-04-23 4 views
3

Я использую Moq на некоторое время, и для краткости я чаще всего не выразить настройки с помощью свободно синтаксис Mock.Of ...AutoFixture и свободно синтаксис Moq

var foo = Mock.Of<IFoo>(f => f.Method(It.IsAny<string>()) == 7 && f.Property == "Hi"); 
var sut = new Whatever(foo); 

В последнее время я начал играя с AutoFixture и не может найти эквивалентный синтаксис для одновременного выражения нескольких настроек. Я понимаю, что я могу выразить то же самое, используя Freeze ...

var foo = fixture.Freeze<Mock<IFoo>>(); 
foo.Setup(f => f.Method(It.IsAny<string>()).Returns(7); 
foo.Setup(f => f.Property).Returns("Hi"); 
var sut = fixture.Create<Whatever>(); 

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

+2

Рассматривали ли вы с помощью NSubstitute? Это OOTB * значительно * более чистое, чем Moq (есть также библиотека клея AutoNSubstitute), поэтому, если у вас нет существенной невыносимой стоимости, у вас нет ничего потерянного, кроме скобок :) –

+2

@RubenBartelink, в данном случае я конкретно работаю с 10k + Moq/NUnit в корпоративной среде, поэтому коммутатор инфраструктуры, вероятно, маловероятен.Тем не менее, для моих личных проектов я определенно посмотрю на это (несколько сравнений, которые я смог найти в Интернете, были совершенно надуманными и сравнили NSubstitute с непроходимым синтаксисом Moq, который довольно «многословен», поэтому мне придется сделать немного исследований и попробовать сами). – ScheuNZ

+0

Отличный смысл в этом контексте: P –

ответ

4

Вы можете создать дразнить себя с помощью текучего API MOq, а затем вводят его обратно в арматуре:

var foo = Mock.Of<IFoo>(f => f.Method(It.IsAny<string>()) == 7 && f.Property == "Hi"); 
fixture.Inject(foo); 

var sut = fixture.Create<Whatever>(); 

Если вы используете AutoMoqCustomization, то код выше будет делать то же самое, как код, который вы опубликовали, кроме того, что не задано CallBase = true и DefaultValue = DefaultValue.Mock;.

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

+0

Nice. Если вы включите помощника и/или объединитесь в моем ответе, я удалю мой, поскольку ключевым моментом, который нужно понять, является тот факт, что autoconfig выбивается с помощью «Inject», как вы говорите. –

+2

@RubenBartelink Я не хочу красть у вас кредиты, давайте продолжим оба ответа;) – dcastro

+0

@dcastro, спасибо - это отвечает на мой вопрос. Я надеялся, что он был выпечен прямо в «Freeze» или один из других методов, так что я мог бы сократить шум, который вводит дополнительный «Mock.Of ». Я уже использовал вспомогательные методы (как расширение, так и экземпляр), чтобы очистить его, чтобы ваш ответ и вспомогательные методы из Рубена были достаточными. Я использую 'AutoMoqCustomization', поэтому использование' Inject' не должно быть проблемой. Еще раз спасибо. – ScheuNZ

4

риффы на @ dcastro отвечают, небольшая обертка, которая будет иметь те же предостережения, как там накрывала: -

public static T SetMock<T>(this IFixture that, Expression<Func<T, bool>> expr) 
    where T : class 
{ 
    var mocked = Mock.Of(expr); 
    that.Inject(mocked); 
    return mocked; 
} 

Позволяет:

fixture.SetMock<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"); 

Или, если и только если вы заинтересованы в конкретное значение:

var foo = fixture.SetMock<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"); 

чистейший C#, без помощников является:

fixture.Inject(Mock.Of<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"))); 

И если вы doing your tests in F# с Foq, можно было бы написать, что, как:

Mock<IFoo>.With(fun x -> 
    <@ x.Method(any()) --> 7 
     x.Property --> "Hi" @>) 
|> fixture.Inject 

(выражение справа от --> просто код, то есть вы можете поместить алгоритмической материал там и вы получаете intellisense и проверку типа, когда вы его пишете). Или (еще с FOQ):

fixture.Inject <| 
    Mock<IFoo>.With(fun x -> <@ 
     x.Method(any()) --> 7 
     x.Property --> "Hi" @>) 

Или (если предположить, что интерфейс имеет смысл, чтобы полностью реализовать), вы можете использовать F # объектные выражения:

fixture.Inject { new IFoo with 
    member x.Method _ = 7 
    member x.Property with get() = "Hi" }