public static void AssignOutAndRefParameterRecordedCall(
            IHaveARef subject, string refValue)
        {
            "Given a fake with a method that has a ref parameter"
            .x(() => subject = A.Fake <IHaveARef>());

            "When the fake is configured to assign out and ref parameters when argument matches condition"
            .x(() =>
            {
                refValue = Condition;
                A.CallTo(() => subject.MightReturnAKnownValue(ref refValue))
                .AssignsOutAndRefParameters(KnownOutput);
            });

            "And the configured method is called"
            .x(() => subject.MightReturnAKnownValue(ref refValue));

            "Then the assertion that a call with the expected value has happened succeeds"
            .x(() =>
            {
                string expectedValue = Condition;
                A.CallTo(() => subject.MightReturnAKnownValue(ref expectedValue)).MustHaveHappened();
            });

            "And the call records the updated arguments"
            .x(() =>
            {
                Fake.GetCalls(subject).First().ArgumentsAfterCall[0].Should().Be(KnownOutput);
            });
        }
        public static void AssignOutAndRefParameters(IHaveARef subject, string outValue)
        {
            "Given a fake with a method that has a ref parameter"
            .x(() => subject = A.Fake <IHaveARef>());

            "When the fake is configured to assign out and ref parameters unconditionally"
            .x(() => A.CallTo(() => subject.MightReturnAKnownValue(ref outValue))
               .WithAnyArguments()
               .AssignsOutAndRefParameters(KnownOutput));

            "And the configured method is called"
            .x(() => subject.MightReturnAKnownValue(ref outValue));

            "Then it assigns the configured value to the ref field"
            .x(() => outValue.Should().BeEquivalentTo(KnownOutput));
        }
        public static void AssignOutAndRefParameters(IHaveARef subject, string outValue)
        {
            "Given a fake with a method that has a ref parameter"
                .x(() => subject = A.Fake<IHaveARef>());

            "When the fake is configured to assign out and ref parameters unconditionally"
                .x(() => A.CallTo(() => subject.MightReturnAKnownValue(ref outValue))
                    .WithAnyArguments()
                    .AssignsOutAndRefParameters(KnownOutput));

            "And the configured method is called"
                .x(() => subject.MightReturnAKnownValue(ref outValue));

            "Then it assigns the configured value to the ref field"
                .x(() => outValue.Should().BeEquivalentTo(KnownOutput));
        }
        public static void MultipleAssignOutAndRefParameters(
            IHaveARef subject, string outValue, IVoidConfiguration callSpec, Exception exception)
        {
            "Given a fake with a method that has a ref parameter"
            .x(() => subject = A.Fake <IHaveARef>());

            "And a call specification on that fake"
            .x(() => callSpec = A.CallTo(() => subject.MightReturnAKnownValue(ref outValue)).WithAnyArguments());

            "And the call specification is configured to assign out and ref parameters"
            .x(() => callSpec.AssignsOutAndRefParameters("test1"));

            "When the fake is configured to assign out and ref parameters again"
            .x(() => exception = Record.Exception(() => callSpec.AssignsOutAndRefParameters("test2")));

            "Then it throws an invalid operation exception"
            .x(() => exception.Should().BeAnExceptionOfType <InvalidOperationException>());
        }
        public static void AssignOutAndRefParametersLazilyUsingCall(IHaveARef subject, string outValue)
        {
            "Given a fake with a method that has a ref parameter"
            .x(() => subject = A.Fake <IHaveARef>());

            "When the fake is configured to assign out and ref parameters lazily using call"
            .x(() => A.CallTo(() => subject.MightReturnAKnownValue(ref outValue))
               .WithAnyArguments()
               .AssignsOutAndRefParametersLazily((call) => new object[]
            {
                call.Arguments.Get <string>(0) == Condition ? KnownOutput : "me"
            }));

            "And the configured method is called with matching arguments"
            .x(() =>
            {
                outValue = Condition;
                subject.MightReturnAKnownValue(ref outValue);
            });

            "Then it assigns the conditional value to the ref field"
            .x(() => outValue.Should().BeEquivalentTo(KnownOutput));
        }
        public static void AssignOutAndRefParametersLazilyUsingCall(IHaveARef subject, string outValue)
        {
            "Given a fake with a method that has a ref parameter"
                .x(() => subject = A.Fake<IHaveARef>());

            "When the fake is configured to assign out and ref parameters lazily using call"
                .x(() => A.CallTo(() => subject.MightReturnAKnownValue(ref outValue))
                    .WithAnyArguments()
                    .AssignsOutAndRefParametersLazily(call => new object[]
                    {
                        call.Arguments.Get<string>(0) == Condition ? KnownOutput : "me"
                    }));

            "And the configured method is called with matching arguments"
                .x(() =>
                {
                    outValue = Condition;
                    subject.MightReturnAKnownValue(ref outValue);
                });

            "Then it assigns the conditional value to the ref field"
                .x(() => outValue.Should().BeEquivalentTo(KnownOutput));
        }
        public static void MultipleAssignOutAndRefParameters(
            IHaveARef subject, string outValue, IVoidConfiguration callSpec, Exception exception)
        {
            "Given a fake with a method that has a ref parameter"
                .x(() => subject = A.Fake<IHaveARef>());

            "And a call specification on that fake"
                .x(() => callSpec = A.CallTo(() => subject.MightReturnAKnownValue(ref outValue)).WithAnyArguments());

            "And the call specification is configured to assign out and ref parameters"
                .x(() => callSpec.AssignsOutAndRefParameters("test1"));

            "When the fake is configured to assign out and ref parameters again"
                .x(() => exception = Record.Exception(() => callSpec.AssignsOutAndRefParameters("test2")));

            "Then it throws an invalid operation exception"
                .x(() => exception.Should().BeAnExceptionOfType<InvalidOperationException>());
        }