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
Welcome to Typemock Answers. Here you can ask and receive answers from other community members. And if you liked or disliked an answer or thread: react with an up- or downvote Enjoy!

How to verify property of fake which was cast to object?

+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 May 4 by Ctvt (2,780 points)

1 Answer

0 votes

Hi Milan,

I tried to solve the problem by creating a list of the faked Field objects, on which you can verify that the calls were made/ not made.

See code below:

[Test] 
public void Test2() 
{

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

    List<Field> testFields = new List<Field>();

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

    testFields.Add(fakeField1);

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

    testFields.Add(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 
    for (int i= 0; i< availableFields.Count; i++)
    { 
        var fieldValue = fieldValues[(availableFields[i] as Field).Name];

        if ((fieldValue % 2) == 0) 
        { 
            Isolate.Verify.WasNotCalled(() => testFields[i].Value =            fieldValue); 
        } 
        else 
        { 
            Isolate.Verify.WasCalledWithExactArguments(() =>        testFields[i].Value = fieldValue); 
        } 
    } 
}

Please let me know if it works out for you.

Cheers,

Sapir.

answered May 6 by SapirTypemock (2,120 points)

Hi Sapir,

Thanks, I got the idea behind your workaround. However in my production code availableFields.Count will be often smaller than fieldValues.Count (not all created fields will be available). 

I think I can tweak your solution to make it work, using Dictionary instead of List, though.

But the ideal solution would be finding a way to cast fakeObject to object and then back to fakeObject.

Is it possible?

Hi Milan,

Object is converted to fakeObject during the foreach statement.

I learned that even if I use this method:

public List<Field> GetFields()
{
        return Fields;
}

that returns the actual list of faked objects, the exception still occurs, so I guess the exception is not connected to the conversion from object to fakeObject and vice versa.

I will continue investigating this and see if I can fix the issue.

Meanwhile, I think that the workaround I suggested is the best way to handle this issue.

I\'ll contact you as soon as there are any updates.

Cheers,

Sapir.

Hi Milan, 

After an investigation, I can say that by design, verifying should be done on the faked objects.

So in your case, the right way is to create a list (or a dictionary) of the faked Field objects and to verify on them.

Cheers,

Sapir. 

...