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
+1 vote

Hi,

I am trying to test if property (List of Field(s)) was initialized correctly in constructor. However I cannot access this property directly, only via method, which cast Field to object

I think, because of the cast, I got back "TypeMock.TypeMockException: ***Cannot verify on real object -use a fake object instead" when trying to verify property was set / not set.

Please see the code example below:

(example should be executable)


class Field
{
    public string Name { get; set; }

    public string Description { get; set; }

    private int? _value;

    public int? Value
    {
        set => _value = value;
    }
}

class FieldSection
{
    private List<Field> Fields { get; }

    public FieldSection(IDictionary<string, int> fieldValues)
    {
        Fields = new List<Field>();

        foreach (var value in fieldValues)
        {
            if ((value.Value % 2) == 0)
            {
                Fields.Add(new Field { Name = value.Key });
            }
            else
            {
                Fields.Add(new Field { Name = value.Key, Value = value.Value }); 
            }
        }
    }

    public List<object> GetAvailableFields()
    {
        return Fields.Select(field => (object) field).ToList();
    }
}

[Test]
public void Test2()
{

    var fieldValues = new Dictionary<string, int> { {\"field1\", 1}, {\"field2\", 2} };

    // fake future objects, which gets created in FieldSection constructor
    var fakeField1 = Isolate.Fake.NextInstance<Field>();
    fakeField1.Description = \"FakeField1\";

    var fakeField2 = Isolate.Fake.NextInstance<Field>();
    fakeField2.Description = \"FakeField2\";

    var fieldSection = new FieldSection(fieldValues);

    // get back fakes via GetAvailableFields(), which cast fakes to objects
    var availableFields = fieldSection.GetAvailableFields();
    
    // verify Field objects were created correctly
    foreach (Field field in availableFields)
    {
        var fieldValue = fieldValues[field.Name];

        if ((fieldValue % 2) == 0)
        {
            Isolate.Verify.WasNotCalled(() => field.Value = fieldValue);
        }
        else
        {
            // here comes the error: TypeMock.TypeMockException : ***Cannot verify on real object -use a fake object instead
            Isolate.Verify.WasCalledWithExactArguments(() => field.Value = fieldValue);
        }
    }
}


How can I cast field from availableFields back to Typemock fake object, so I will not get an error?

asked by Ctvt (2.7k points)

1 Answer

0 votes

One option to fix this error would be to change the return type of the GetAvailableFields method to a list of Field objects instead of a list of object objects, so you can directly access the Field objects in your test without having to cast them.

Alternatively, if you want to keep the return type of GetAvailableFields as a list of object objects, you can use the As method of the Isolate class to cast the objects in the list back to their original fake Field objects before verifying the calls on them.

Here's how you can modify your test to use the As method:

[Test]

public void Test2()

{

    var fieldValues = new Dictionary<string, int> { {"field1", 1}, {"field2", 2} };

    // fake future objects, which gets created in FieldSection constructor

    var fakeField1 = Isolate.Fake.NextInstance<Field>();

    fakeField1.Description = "FakeField1";

    var fakeField2 = Isolate.Fake.NextInstance<Field>();

    fakeField2.Description = "FakeField2";

    var fieldSection = new FieldSection(fieldValues);

    // get back fakes via GetAvailableFields(), which cast fakes to objects

    var availableFields = fieldSection.GetAvailableFields();

    

    // verify Field objects were created correctly

    foreach (object obj in availableFields)

    {

        var field = Isolate.As<Field>(obj);

        var fieldValue = fieldValues[field.Name];

        if ((fieldValue % 2) == 0)

        {

            Isolate.Verify.WasNotCalled(() => field.Value = fieldValue);

        }

        else

        {

            Isolate.Verify.WasCalledWithExactArguments(() => field.Value = fieldValue);

        }

    }

}

This should fix the error you are seeing. I hope.

answered by Johnathon00 (190 points)
...