chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male

Verify matching arguments in WasCalledWithArguments on recursive fake

+2 votes

Hi,

I am having toruble with veryfing matching argumetns for recursive fake object.

The "args" in matching predicate is empty object array ( {object[0]} ), therefore getting IndexOutOfRangeException.

When debugging, I see "createParameters.GetField(details.Name, details.Step.Name);" returned  fakeStepInputField.

This is code in my Unit Test:


    // ARRANGE
    var fakeDetails = Isolate.Fake.NextInstance<WorkflowStep.DetailsSection>();

    Isolate.WhenCalled(() => fakeDetails.Name).WillReturn("Details");
    Isolate.WhenCalled(() => fakeDetails.Step.Name).WillReturn("Step");

    var fakeCreateParameters = Isolate.Fake.Instance<CreateParameters>();
    var fakeStepInputField = Isolate.Fake.Instance<InputField>();

    Isolate.WhenCalled(() => fakeCreateParameters.GetField("Details", "Step")).WithExactArguments().WillReturn(fakeStepInputField);

    var controller = new StepController();

    // ACT
    controller.Create(fakeCreateParameters);

    // ASSERT
    Isolate.Verify.WasCalledWithArguments(() => fakeDetails.Step.SetReceivedValue(null)).Matching(
        args =>
	{
             return (InputField) args[0] == fakeStepInputField;
        });

 

The code under test:

    public class StepController
    {
        public void Create(CreateParameters createParameters)
        {
            var details = new WorkflowStep.DetailsSection();
			
            var stepInputField = createParameters.GetField(details.Name, details.Step.Name);
            details.Step.SetReceivedValue(stepInputField);
			
            // ...
        }
    }

Thanks.

asked Nov 2, 2017 by Ctvt (2,780 points)
edited Nov 4, 2017 by Ctvt

1 Answer

0 votes
 
Best answer

For the moment you can use:

Isolate.Verify.WasCalledWithExactArguments(() => fakeDetails.Step.SetReceivedValue(fakeStepInputField));

We'll investigate why this error is thrown.

answered Nov 5, 2017 by Raphy (3,660 points)
selected Nov 8, 2017 by Ctvt

Hi Raphy,

thanks that worked for this case and also simple types (int, bool, ...).

However on some places I need to check argument of setter using "Matching". Example of such case is, when I need to check if the list of items was set correctly:

Isolate.Verify.WasCalledWithArguments(() => fakeDetails.StepType.ListItems = null).Matching(
    args =>
    {
        var stepTypes = (List<ListItem>)args[0];

        return 
            stepTypes.Count == 2 &&
            stepTypes.Exists(st => st.Text.Equals("First step"));
    });

In this case I am also getting "IndexOutOfRangeException".

I found workaround though and the following will work:

var detailsStepType = fakeDetails.StepType;

Isolate.Verify.WasCalledWithArguments(() => detailsStepType.ListItems = null).Matching(
    args =>
    {
        var stepTypes = (List<ListItem>)args[0];

        return 
            stepTypes.Count == 2 &&
            stepTypes.Exists(st => st.Text.Equals("First step"));
    });

Is this correct way to call delegate and do custom arguments matching or is it a bug? It feels like a latter to me.

Thanks.

Yes, it is a bug from what we've checked so far.

I'll update you once we fix it.

By extracting the "Step" property and asserting against it does work:

var step = fakeDetails.Step;
 
// ASSERT
Isolate.Verify.WasCalledWithArguments(() => step.SetReceivedValue(null)).Matching(
args =>
{
             return ((args[0] as InputField) == fakeStepInputField);
 });

There might be a bug in verifying chained calls.

...