5 Stimmen

Unit Test Service mit WCF-Aufruf (MSUnit + Moq)

Ich bin neu in Mocking und etwas vertraut mit Unit-Tests und schließlich haben beschlossen, beißen die Kugel auf ein neues Projekt ab vorne mit einer strengen TDD-Ansatz. Allerdings habe ich eine Serviceklasse und Methode, die ich brauche, um rückwirkend Tests hinzufügen, wie es von einem Prototyp gefördert wurde.

Ich weiß nicht, wo ich bei diesem speziellen Test anfangen soll, das sind die beteiligten Klassen und Methoden:

public class PageService : IPageService
{
    private readonly ITestService testServiceClient;

    public PageService(ITestService testServiceClient)
    {
        this.testServiceClient = testServiceClient;
    }

    public Page GetPage(Guid websiteId, string pageKey)
    {
        Page builtPage = null;

        // WCF SERVICE CALL I DO NOT WANT EXECUTING WHEN RUNNING UNIT TEST
        // BUT RATHER WANT A BLANK NEW INSTANCE OF "PAGE" CREATED USING MOQ??
        var page = testServiceClient.GetPage(websiteId, pageKey);

        if (page == null)
            return null;

        builtPage = new Page();

        [code here to build builtPage if input params ok] ...

        return builtPage;
    }
}

Was ich zu tun versuche, ist, einen Test zu schreiben, von dem aus ich hoffentlich alle Permutationen von GetPage(...) Tests, aber für den ersten wird einfach geprüft, ob ein gültiger websiteId y pageKey übergeben wurde, wenn ja, erhalten Sie eine gültige Page Instanz zurück und bestätigen true für den Einheitstest.

testServiceClient ein WCF-Dienst-Client ist, wurde dieser in eine using() Anweisung, aber ich habe es aus diesem in der Hoffnung verschoben, um es mit Abhängigkeit Injektion, wie ich glaube, dass der erste Schritt für die Prüfung erforderlich sein wird, wie von dem, was ich verstehe, muss ich es eine gefälschte / mocked? wcf Client statt wo testServiceClient.GetPage() eine bekannte speicherinterne Menge von Daten zurückgibt? Hoffentlich bin ich hier auf dem richtigen Weg.

Also hier ist meine anfängliche Entwürfe meiner Unit-Test (Ich bin mit Moq Rahmen, Setup() ist die neue Version von Expect() wenn Sie nicht die neueste Version von Moq verwenden):

/// <summary>
/// Tests service returns a valid instance of type `Page` when a valid website and valid page key is tested.
/// </summary>
[TestMethod]
public void Test_Valid_Website_And_Valid_PageKey_Returns_Valid_Instance_Of_Page()
{
    // Arrange
    Page page = null;

    // Act
    var newPage = new Page() { Title = "Mocked Version!?"};

    testServiceClient = new Mock<ITestService>();
    testServiceClient.Setup(x => x.GetPage(websiteId, "about-us")).Returns(newPage);

    service = new PageService(testServiceClient.Object);
    page = service.GetPage(websiteId, "about-us");

    // Assert
    Assert.IsInstanceOfType(page, typeof(Page), "Object was not of expected instance type.");
}

Ich habe keine Ahnung, wie es weitergehen soll, oder ob ich auf dem richtigen Weg bin. Ich kann bestätigen, dass die obige Eingabe keine Syntaxfehler enthält, und ich erhalte eine Ausnahme:

System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetPage(websiteId, "about-us").

Ich weiß nur, dass ich meine service.GetPage(...) um eine neue Instanz zurückzugeben, wie websiteId y pageKey gültig war, aber ich möchte nicht, dass es die echte testServiceClient.GetPage() WCF-Aufruf... hoffentlich verstehe ich die Idee des Mocking richtig. Habe ich es richtig gesagt durch Moq, wenn Sie verwenden testServiceClient.GetPage auf diesen Dienst, eigentlich nur eine neue Instanz von page?

Jede Klarstellung ist sehr willkommen! Danke Jungs!

4voto

Mark Seemann Punkte 216836

Ich würde sagen, dass Sie auf dem richtigen Weg sind. Wenn ITestService wirklich eine Schnittstelle ist (wie durch den Namen angedeutet), werden Sie in der Lage sein, Mock es.

Wenn Sie jedoch Ihre Setups definieren, muss Moq in der Lage sein zu erkennen, welche Methode Sie gemeint haben, und es scheint, als ob Sie irgendwie eine Methode angeben, die es auf der Schnittstelle nicht gibt.

Sie haben uns die ITestService-Schnittstelle nicht gezeigt, und wir kennen auch nicht den Typ der websiteId variabel.

Wenn Sie sich die Setup-Methode genauer ansehen, werden Sie feststellen, dass es sich in Wirklichkeit um eine generische Methode handelt, d. h. es findet eine Typinferenz statt, wenn Sie sie ohne die generischen Parameter aufrufen.

Ich vermute, dass die Erklärung von websiteId kollidiert irgendwie mit der Erklärung von GetPage. Wenn, zum Beispiel, websiteId wurde erklärt als object Moq würde sich um eine Methode mit dieser Signatur kümmern:

Page GetPage(object x, string y);

was nicht dasselbe ist wie

Page GetPage(Guid x, string y);

In jedem Fall, wenn Sie es schaffen, das Setup zum Laufen zu bringen, scheint Ihre Grundidee über den Einheitstest in Ordnung zu sein. Sie können mehr tun, als nur zu behaupten, dass die Instanz nicht null ist, weil der Mock sicherstellen wird, dass die zurückgegebene Instanz die gleiche ist wie die Instanz, die Sie ursprünglich eingerichtet haben:

[TestMethod]
public void Test_Valid_Website_And_Valid_PageKey_Returns_Valid_Instance_Of_Page()
{
    // Arrange
    Page page = null;

    // Act
    var newPage = new Page() { Title = "Mocked Version!?"};

    testServiceClient = new Mock<ITestService>();
    testServiceClient.Setup(x => x.GetPage(websiteId, "about-us")).Returns(newPage);

    service = new PageService(testServiceClient.Object);
    page = service.GetPage(websiteId, "about-us");

    // Assert
    Assert.AreEqual(newPage, page);
}

Beachten Sie das viel wertvollere Assert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X