Как мне макетировать параметры с помощью Machine.Fakes независимо от макета фреймворка? - PullRequest
2 голосов
/ 04 января 2012

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

Проблема в том, что это привело к сбою "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.

Ответы [ 3 ]

7 голосов
/ 05 января 2012

Machine.Fakes не справляется с этим сценарием.Это просто не реализовано.

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

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

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

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

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

  • Bjoern
5 голосов
/ 04 января 2012

Похоже, что для этого случая вам нужно использовать 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);
  }
}
1 голос
/ 02 августа 2013

Начиная с версии 1.7.0 Machine.Fakes поддерживает настройку параметров out и ref в поддельных вызовах - при использовании адаптеров FakeItEasy или NSubstitute.Таким образом, вам больше не нужно использовать 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 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);
    }
}
...