Перекрывание свойства в фейковом объекте

Есть продакшен код вот такого вида:

public class User : UserBase
{
    public int Age { get; set; }

    //...
}

public class UserBase
{
    public AddressType AddressType { get; }

    //...
}

public class AddressType : AddressTypeBase
{
    //...
}

public abstract class AddressTypeBase
{
    public string Code { get; }

    //...
}

Пытаюсь написать юнит-тест для метода, который принимает объект User в качестве параметра. В данном методе идет обращение к свойству User.AddressType.Code, а его инициализация в тестовом окружении очень сложна. Я пытался с помощью Moq как-то замокать это дело, но ничего не вышло.

Теперь решил посредством создания фейкового объекта:

public class FakeUser : User
{
    public new AddressType AddressType => new FakeAddressType("TestCode");

    public class FakeAddressType : AddressType
    {
        public new string Code { get; }

        public FakeAddressType(string code)
        {
            Code = code;
        }
    }
}

И вроде как все получилось, но результат вызова:

class Program
{
    static void Main(string[] args)
    {
        var fakeUser = new FakeUser();
        var addressTypeCode = fakeUser.AddressType.Code;
    }
}

таков:

введите сюда описание изображения

Происходит некая магия c наследованием и я пытаюсь разобраться что к чему:

введите сюда описание изображения

Я думал, что если базовый вариант свойства перекрывается посредством new AddressType AddressType, то ссылка FakeUser сможет обращаться только к своей копии этого свойства. Но на скриншоте выше можно увидеть, что она хранит оба варианта или быть может VS и ReSharper мне неверно что-то подсказывают. В любом случае, при обращении к fakeUser.AddressType.Code был вызван базовый вариант.

Что я неправильно делаю и можно ли вообще как-то замокать это свойство тем подходом, что я пытаюсь применить?


Ответы (1 шт):

Автор решения: aepot

Вот так с кастом будет работать, подходит ли вам такой вариант?

var addressTypeCode = ((FakeAddressType)fakeUser.AddressType).Code;

Ну либо вот такой вариант вместо предыдущего

public new FakeAddressType AddressType => new FakeAddressType("TestCode");

Просто по умолчанию берется то значение свойства, которое соответствует его типу, чтобы взять переопределенное, нужно либо тип переопределенного значения использовать, либо каст в этот тип, собственно это и показано выше.

→ Ссылка