В следующем примере кода у меня есть класс Async Calculator. Это вводится ICalc, который будет синхронным калькулятором. Я использую инъекцию зависимостей и издеваюсь над ICalc, потому что это похоже на мой истинный сценарий, хотя я думаю, что издевательство действительно не имеет отношения к вопросу. AsyncCalc имеет функцию, которая будет асинхронно вызывать другую функцию - выбор параметра обратного вызова в качестве параметра. И когда вызов функции асинхронной связи завершит обратный вызов, будет вызван результат.
Теперь я хочу проверить свою асинхронную функцию - проверку того, что обратный вызов запускается с ожидаемым параметром. Этот код, похоже, работает. Тем не менее, я чувствую, что он может взорваться в любое время - и моя озабоченность связана с состоянием гонки в обратном вызове до завершения функции и завершения теста - поскольку это будет выполняться в отдельном потоке.
Теперь мой вопрос, если я нахожусь на правильном пути, проверяя функцию async, или кто-нибудь может помочь мне встать на правильный путь..? Что было бы лучше, если бы я мог убедиться, что обратный вызов запускается сразу - и, желательно, по той же теме, я думаю? Может/Должно ли это быть сделано?
public interface ICalc
{
int AddNumbers(int a, int b);
}
public class AsyncCalc
{
private readonly ICalc _calc;
public delegate void ResultProcessor(int result);
public delegate int AddNumbersAsyncCaller(int a, int b);
public AsyncCalc(ICalc calc)
{
_calc = calc;
}
public void AddNumbers(int a, int b, ResultProcessor resultProcessor)
{
var caller = new AddNumbersAsyncCaller(_calc.AddNumbers);
caller.BeginInvoke(a, b, new AsyncCallback(AddNumbersCallbackMethod), resultProcessor);
}
public void AddNumbersCallbackMethod(IAsyncResult ar)
{
var result = (AsyncResult)ar;
var caller = (AddNumbersAsyncCaller)result.AsyncDelegate;
var resultFromAdd = caller.EndInvoke(ar);
var resultProcessor = ar.AsyncState as ResultProcessor;
if (resultProcessor == null) return;
resultProcessor(resultFromAdd);
}
}
[Test]
public void TestingAsyncCalc()
{
var mocks = new MockRepository();
var fakeCalc = mocks.DynamicMock<ICalc>();
using (mocks.Record())
{
fakeCalc.AddNumbers(1, 2);
LastCall.Return(3);
}
var asyncCalc = new AsyncCalc(fakeCalc);
asyncCalc.AddNumbers(1, 2, TestResultProcessor);
}
public void TestResultProcessor(int result)
{
Assert.AreEqual(3, result);
}