Verify matching arguments in WasCalledWithArguments on recursive fake

+1 vote

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 by Ctvt (230 points)
edited Nov 4 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 by Raphy (2,070 points)
selected Nov 8 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.

...