2010-03-25 6 views
9

У меня есть класс, который примерно выглядит следующим образом:Как я могу издеваться над этим асинхронным методом?

public class ViewModel 
{ 
    public ViewModel(IWebService service) 
    { 
    this.WebService = service; 
    } 

    private IWebService WebService{get;set;} 
    private IEnumerable<SomeData> MyData{get;set;} 

    private void GetReferenceData() 
    { 
    this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null); 
    } 

    private void GetReferenceDataOnComplete(IAsyncResult result) 
    { 
    this.MyData = this.WebService.EndGetStaticReferenceData(result); 
    } 
    . 
    . 
    . 
} 

Я хочу, чтобы дразнить мой интерфейс IWebService так, что, когда BeginGetStaticReferenceData называется она способна вызвать метод обратного вызова. Я использую Moq, и я не могу понять, как это сделать. Мой блок тест установить код выглядит примерно так:

//Arrange 
var service = new Mock<IWebService>(); 
service.Setup(x => x.BeginGetStaticReferenceData(/*.......don't know.....*/)); 
service.Setup(x => x.EndGetStaticReferenceData(It.IsAny<IAsyncResult>())).Returns(new List<SomeData>{new SomeData{Name="blah"}}); 
var viewModel = new ViewModel(service.Object); 
. 
. 

ответ

19

Вот как:

[TestMethod] 
public void Test10() 
{ 
    var expectedData = new[]{new SomeData(), new SomeData()}; 

    AsyncCallback callback = null; 
    IAsyncResult ar = new Mock<IAsyncResult>().Object; 

    var webServiceStub = new Mock<IWebService>(); 
    webServiceStub 
     .Setup(ws => ws.BeginGetStaticReferenceData(It.IsAny<AsyncCallback>(), null)) 
     .Callback((AsyncCallback cb, object state) => callback = cb) 
     .Returns(ar); 
    webServiceStub 
     .Setup(ws => ws.EndGetStaticReferenceData(It.IsAny<IAsyncResult>())) 
     .Returns(expectedData); 

    var sut = new ViewModel(webServiceStub.Object); 
    sut.DoIt(); 

    callback(ar); 

    Assert.AreEqual(expectedData, sut.MyData); 
} 

Этот тест предполагает немного измененную ViewModel, где я добавил несколько представителей общественности, чтобы иметь что-то, против которого в тесте:

public class ViewModel 
{ 
    public ViewModel(IWebService service) 
    { 
     this.WebService = service; 
    } 

    public IEnumerable<SomeData> MyData { get; set; } 

    public void DoIt() 
    { 
     this.GetReferenceData(); 
    } 

    private IWebService WebService { get; set; } 

    private void GetReferenceData() 
    { 
     this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null); 
    } 

    private void GetReferenceDataOnComplete(IAsyncResult result) 
    { 
     this.MyData = this.WebService.EndGetStaticReferenceData(result); 
    } 
} 
+0

Отлично, это прекрасно работало. Спасибо! – Charlie

+0

Я пробовал адаптировать это для UdpClient, и он работал только в том случае, если я изменил обратный вызов с '=> callback = cb' на' => cb (ar) '. Не уверен, что я взломал монстра или что ... – Benjol

+0

Что такое класс Mock для выше? Это ваш класс или мне нужно добавить ссылку на его использование? –

0

article Это содержит очень хорошее объяснение о том, как проверить асинхронные методы с использованием Rhino Mocks - Я уверен, что он может быть легко адаптирован для использования Moq вместо.

Смежные вопросы