2010-03-25 23 views
9

Mam klasy, które z grubsza wygląda tak:Jak mogę kpić z tej asynchronicznej metody?

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); 
    } 
    . 
    . 
    . 
} 

chcę drwić mój interfejs IWebService tak, że kiedy BeginGetStaticReferenceData nazywa jest w stanie wywołać metodę wywołania zwrotnego. Używam Moq i nie mogę się dowiedzieć, jak to zrobić. Moje testy jednostkowe skonfigurować kod wygląda mniej więcej tak:

//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); 
. 
. 

Odpowiedz

19

Oto jak:

[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); 
} 

Test ten zakłada nieco zmodyfikowaną ViewModel gdzie dodałem kilku członków publiczne mają coś przeciwko którym do testu:

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

niesamowite, to było wspaniałe. Dziękuję Ci! – Charlie

+0

Próbowałem dostosować to dla UdpClient i działało to tylko wtedy, gdy zmieniłem twoje wywołanie zwrotne z '=> callback = cb' na' => cb (ar) '. Nie jestem pewien, czy zhackowałem potwora, czy co ... – Benjol

+0

Co to jest klasa Mock dla powyższego? Czy jest to twoja klasa lub muszę dodać jakieś odniesienie do jej użycia? –

0

article ten zawiera bardzo dobre wyjaśnienie, w jaki sposób przetestować metody async przy użyciu Rhino Mocks - Jestem pewien, że można go łatwo dostosować do korzystania Min zamiast.

Powiązane problemy