#c# #wpf #nunit #moq
#c# #wpf #nunit #moq
Вопрос:
У меня есть метод, который возвращает DispatcherOperation<TResult>
объект:
public DispatcherOperation<TResult> InvokeAsync<TResult>(Func<TResult> callback)
{
return this.UIDispatcher.InvokeAsync(callback);
}
Как он используется в приложении:
var res = await this.dispatcher.InvokeAsync(() =>
{
// returns a List<string> by computing some logic
});
И я издевался над этим методом, используя moq:
this.mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<List<string>>())).Callback((Func<List<string>> callback) => callback.Invoke());
но проблема в том, что вызывающий метод не ожидает ответа и заканчивается нулевым исключением.
Я знаю, что обратный вызов не следует использовать для возврата значений, но я не могу определить метод возврата, который может возвращать результат типа DispatcherOperation<T>
Вот что я пытаюсь:
this.mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<List<string>>>())).Returns((Func<List<string>> callback) => callback()));
Как мне вернуть его как DispatcherOperation<List<string>>
Комментарии:
1. Вам не нужно звонить
callback
?.Returns(callback => callback())
2. @AluanHaddad Я отредактировал вопрос с правильным синтаксисом, меня беспокоит, что он возвращается
List<string>
туда, где мне нужноDispatcherOperation<List<string>>
3. Я вижу. Я не думаю, что вы можете, потому что конструктор
DispatcherOperation<TResult>
является внутренним.4. @AluanHaddad итак, вы говорите, что нет другого способа высмеять это, кроме как вернуть измененный результат? подождите, даже это невозможно, не так ли
5. К сожалению, нет.
Ответ №1:
Вы можете Task<T>
довольно легко издеваться над:
public Task<TResult> InvokeAsync<TResult>(Func<TResult> callback)
{
return this.UIDispatcher.InvokeAsync(callback).Task;
}
this.mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<List<string>>())).Callback((Func<List<string>> callback) => Task.FromResult(callback.Invoke()));
Гораздо проще издеваться над типом общего назначения, подобным Task<T>
, а не над типом, специфичным для фреймворка DispatcherOperation<TResult>
. Однако, если вы должны использовать DispatcherOperation<TResult>
, у вас также есть возможность создать тестовый Dispatcher
экземпляр (и выполнить всю перекачку сообщений и все необходимое с помощью гораздо более тяжелого макета, подобного этому).
Комментарии:
1. вы пропустили
>
, кроме того, что это сработало как шарм, я не знал, что вы можете реализовать это таким образом, это было именно то, что мне было нужно.2. Единственная проблема заключается в том, почему я не могу сделать его универсальным, например
It.IsAny<Func<It.IsAnyType>>
, вместо того, чтобы привязывать его к типу параметра метода.3. @ThePiatre: я не очень хорошо знаком с такого рода плавным издевательством, поэтому я не знаю, есть ли способ заставить это работать.