2012-01-04 4 views
3

Я ударил в тупик с помощью Machine.Fakes. Я не могу понять, как издеваться над параметром out, используя только Machine.Fakes equipment. Из-за a bug в RhinoMocks я переключил адаптер mfakes на FakeItEasy. Насколько я могу судить, любой из адаптеров должен быть взаимозаменяемым.Как мне издеваться над параметрами с помощью Machine.Fakes независимо от фреймов?

Проблема в том, что это привело к тому, что тесты «out» потерпели неудачу, все, что было похоже на это, больше не компилируется, потому что Arg был Rhino.Mocks.

The<IMembershipService>() 
    .WhenToldTo(x => x.CreateUser(Param<string>.IsAnything, 
     Param<bool>.IsAnything, 
     Param<object>.IsAnything, 
     out Arg<MembershipCreateStatus> 
      .Out(MembershipCreateStatus.UserRejected) 
      .Dummy)) 
    .Return(user); 

Я попытался с помощью «фиктивного» локальной переменного, установить на то же значение оригинала Arg<T> пары установить его, но это вызвало мои тесты на провал - кажется, что значение не является прошел сквозь! Arg<T> действительно имел решение, но я больше не могу его использовать, так как это часть Rhino.Mocks.

ответ

2

Начиная с версией 1.7.0 Machine.Fakes поддерживает создание out и ref параметров в поддельных звонках - когда используя адаптеры FakeItEasy или NSubstitute. Таким образом, вам больше не нужно использовать FakeItEasy. Пример Alex 'можно упростить следующим образом:

using Machine.Fakes; 
using Machine.Specifications; 

namespace MSpecMFakesOutParam 
{ 
    public interface IFoo 
    { 
     void Foo(out int foo); 
    } 

    public class When_using_FakeItEasy_with_out_params : WithFakes 
    { 
     static int Out; 

     Establish context =() => 
     { 
      int ignored; 
      The<IFoo>().WhenToldTo(x => x.Foo(out ignored)).AssignOutAndRefParameters(42); 
     }; 

     Because of =() => The<IFoo>().Foo(out Out); 

     It should_assign_the_out_param =() => Out.ShouldEqual(42); 
    } 
} 
+0

+1 для обновления.Похоже, это работает только на пустых методах? Кажется немного ограниченным, поскольку во многих случаях параметр «out» используется для возврата дополнительного возвращаемого значения. – MattDavey

+0

Да, @MattDavey, я применил это только для методов void. Я согласен, что это ограничение, но его реализация для запросов осложнила бы API. –

+0

Кроме того, поддержка параметров не была первоначально реализована, потому что они считались плохим дизайном. Я думаю, что это вариант, который стоит иметь, поскольку даже .NET Framework использует параметры. Но я бы не зашел так далеко, чтобы сказать возвращаемое значение. И параметр out в одном методе - хороший дизайн. Я бы сказал, либо вернул кортеж, либо имел несколько параметров. Таким образом, я сохранил MFakes таким образом. –

5

Кажется, что для этого случая вам нужно напрямую использовать FakeItEasy. Я думаю, что проблема заключается в том, как FakeItEasy требует, чтобы вы установили параметры out, добавив AssignsOutAndRefParameters в спецификацию вызова фальшивых объектов. Это не должно быть проблемой, хотя, поскольку все, что Machine.Fakes делает, переводит WhenToldTo и т. Д. В соответствующий API используемой фальсификации.

using FakeItEasy; 

using Machine.Fakes; 
using Machine.Specifications; 

namespace MSpecMFakesOutParam 
{ 
    public interface IFoo 
    { 
    void Foo(out int foo); 
    } 

    public class When_using_FakeItEasy_with_out_params : WithFakes 
    { 
    static IFoo Foo; 
    static int Out; 

    Establish context =() => 
    { 
     Foo = An<IFoo>(); 

     var ignored = A<int>.Ignored; 
     A.CallTo(() => Foo.Foo(out ignored)).AssignsOutAndRefParameters(42); 
    }; 

    Because of =() => Foo.Foo(out Out); 

    It should_assign_the_out_param = 
    () => Out.ShouldEqual(42); 
    } 
} 
8

Machine.Fakes не обрабатывает этот сценарий. Это просто не реализовано.

Я лично не использую параметры и (если мне действительно нужно возвращать несколько возвращаемых значений) используйте кортеж (Tuple < T, K >) или пользовательский класс для таких сценариев. Вот почему это никогда не было действительно высоким по моему приоритету.

Я не изучал его, но возможно, что реализация обработки параметров ref и out в Machine.Fakes невозможна. Одна из проблем, связанных с внедрением оболочки поверх нескольких издевательских фреймворков, заключается в том, что для того, чтобы добиться успеха, все издевательские структуры должны иметь общий знаменатель в том, как они работают. Machine.Fakes также не поддерживает насмешливые события прямо сейчас, потому что я не смог найти общий знаменатель для всех из них (только для двух NSubstitute/FakeItEasy против Rhino/Moq).

Как я вижу тебя в настоящее время два варианта:

  1. Если вы контролируете интерфейс мы говорим о, вы можете обойти эту проблему с помощью кортежа или пользовательского класса.
  2. Если вы не владеете интерфейсом, вы всегда можете вернуться к базовой структуре фальшивки для таких случаев, как предложил Александр Гросс.

Извините за не давая вам лучший ответ ;-)

  • Бьорн