Макет интерфейса <T> - PullRequest
       65

Макет интерфейса <T>

0 голосов
/ 17 апреля 2020

Как работает один интерфейс mock / moq для T

  public interface IClient<T>
  {
    Task Call(Expression<Func<T, Task>> expression);
  }

  public interface IRepository {
    Task Get(int id);
  }

Я пытаюсь смоделировать выражения Call и Get следующим образом:

Mock<IClient<IRepository>> mock = new Mock<IClient<IRepository>>();

// Setup
mock.Setup(x => x.Call(s => s.Get(1))).ReturnsAsync(new Value());

// always returns null
var result = await mock.Object.Call(s => s.Get(1));

Я пытаюсь проверить IRepository. Get () метод. Когда я настраиваю его сам, он работает. Но когда я обертываю его внутри IClient, результат будет нулевым.

1 Ответ

0 голосов
/ 17 апреля 2020

Проблема не в том, что вы пытаетесь смоделировать универсальный c интерфейс; проблема в том, что метод, который вы пытаетесь смоделировать, имеет возвращаемый тип Task, асинхронный эквивалент void. Нет смысла пытаться имитировать его, чтобы вернуть значение.

Какого типа вы ожидаете, что метод Call на вашем IClient интерфейсе вернется?

Здесь я настроил ваш интерфейс, добавив дополнительный параметр типа U для типа возвращаемого значения метода Call:

public interface IClient<T, U>
{
    Task<U> Call(Expression<Func<T, Task>> expression);
}

Затем в следующем модульном тесте я смоделировал это вернуть целое число 123:

[Fact]
public async Task MockingAnAsynchronousMethod()
{
    var mock = new Mock<IClient<IRepository, int>>();

    // Setup
    mock.Setup(x => x.Call(s => s.Get(1))).ReturnsAsync(123);

    var result = await mock.Object.Call(s => s.Get(1));
    Assert.Equal(123, result);
}
...