Создайте объект с вложенным свойством, у которого нет интерфейса - PullRequest
0 голосов
/ 05 августа 2020

У нас есть следующий код, чтобы проверить, работает ли он:

Car car = await someService.CreateAsync(wheels);
List<string> urls = car.Input.Endpoints.Select(x => x.Url);

Теперь я пытаюсь имитировать машину, возвращенную someService в первой строке, чтобы проверить вторую строку. Я пробовал это:

var car = new Mock<Car>();
var carEndpoint = new CarEndpoint(url: "http://google.com");
car.Object.Input.Endpoints.Add(carEndpoint);

var someService = new Mock<ISomeService>();
someService.Setup(o => o.CreateAsync(It.IsAny<Wheels>())).ReturnsAsync(car.Object);

var myClass = new ClassToTest(someService.Object);
...

Но выдает ошибку

System.NotSupportedException: 'Неподдерживаемое выражение: .... Конечные точки Непереопределяемые элементы (здесь: Input.get_Endpoints ) не может использоваться в выражениях настройки / проверки. '

Проблема в том, что Car создается someService, который я не могу изменить, и ни Car, ни Input не реализуют какой-либо интерфейс. Как я могу поиздеваться над этим, чтобы протестировать вторую строку сверху?

List<string> urls = car.Input.Endpoints.Select(x => x.Url);

По просьбе я покидаю класс Car (упрощенный):

namespace X
{
    [JsonTransformation]
    public class Car : AnotherClass
    {
        public Car();
    
        public Car(CarInput input, string description, ...);

        [JsonProperty(PropertyName = "properties.description")]
        public string Description { get; set; }

        [JsonProperty(PropertyName = "properties.input")]
        public CarInput Input { get; set; }
        
        ...
    }
}

Это было предложили создать объект вручную без Moq, для этого нам пришлось написать много строк, так как, во-первых, потому что вторая строка - не единственное свойство, которое мы тестируем (помните, что это упрощенный сценарий), а во-вторых, нам пришлось везде ставить новые для создания структуры, необходимой для вложенных свойств. Как этого избежать, если мы не можем изменить класс Car и у него нет интерфейса.

1 Ответ

2 голосов
/ 05 августа 2020

Итак, учитывая то, что Автомобиль внесен в список более или менее POCO, почему бы не просто

var car = new Car();
var carEndpoint = new CarEndpoint(url: "http://google.com");
car.Input = new CarInput { Endpoints = new [] { carEndpoint } }; 
// or convert the above to list or whatever you have

var someService = new Mock<ISomeService>();
someService.Setup(o => o.CreateAsync(It.IsAny<Wheels>())).ReturnsAsync(car);

var myClass = new ClassToTest(someService.Object);
...