2010-11-01 17 views
9

Jaki jest najlepszy sposób testowania spodziewanych błędów z usług WCF?Testowanie jednostki Błędy WCF

Próbuję przetestować usługę WCF, która jest (poprawnie) wyrzucaniem usterek w przypadku pewnego odtwarzalnego błędu. Testy jednostkowe pobierają instancję klienta WCF i wywołują odpowiednią metodę usługi, która wywołuje wyjątek FaultException.

Wszystko to działa tak, jak można by oczekiwać, ale mam trudności z testowaniem tego urządzenia, ponieważ błąd powoduje przerwanie IDE, gdy błąd nie zostanie wykryty podczas wdrażania usługi. Ponieważ używam błędów, a nie wyjątków, oczekiwałem, że IDE będzie serializować wyjątek i wysłać go do klienta, gdzie podniósłby wyjątek.

Widzę, że istnieje opcja konfiguracji wyłączania łamania dla konkretnych nieobsługiwanych wyjątków, ale miałem nadzieję, że ktoś może wskazać lepszy sposób osiągnięcia tych samych wyników, ponieważ nie jest to łatwe do zrealizowania w zespole środowisko.

Oto niektóre przykładowy kod z czego realizacja obecnie wygląda ...

Projekt Test jednostka ma odniesienie usługa mój usług WCF, a ja zdefiniowany interfejs, takie jak:

[OperationContract(Name = "DoSomething")] 
[FaultContract(typeof(EpicFail))] 
ResponseObject DoSomething(RequestObject requestObject); 

usterka jest zdefiniowany jako takie:

[DataContract] 
public class EpicFail 
{ 

    public EpicFail(string action) 
    { 
     this.Reason = "Epic Fail"; 
     this.Action = action; 
    } 

    [DataMember] 
    public string Reason 
    { 
     get; 
     set; 
    } 

    [DataMember] 
    public string Action 
    { 
     get; 
     set; 
    } 

} 

Kod, który wywołuje usługę niejasno wygląda tak:

[TestMethod()] 
[ExpectedException(typeof(FaultException<EpicFail>))] 
public void FaultTest_Fails_Epicly() 
{ 
    bool testPassed = false; 

    try 
    { 
     ResponseObject resp = GetServiceClient().DoSomething(req); 
    } 
    catch (FaultException<EpicFail>) 
    { 
     testPassed = true; 
    } 

    Assert.IsTrue(testPassed); 
} 
  • edytowany kod, aby pokazać, że używam atrybut ExpectedException i nie wydaje się mieć większego wpływu na utrzymanie IDE/Debugger pękaniu, gdy jest wyjątek w serwisie.
+0

Czy udostępniającym usługę WCF w tym samym procesie co testów jednostkowych, lub w oddzielnym procesie? –

+0

Oddzielne procesy, usługa WCF jest hostowana za pośrednictwem IIS. Prowadzę testy jednostek lokalnie w trybie debugowania. Oba projekty są częścią tego samego rozwiązania. Myślę, że jeśli uruchomię usługę w trybie budowania, a urządzenie będzie testować w trybie debugowania, prawdopodobnie naprawi problem, ale to nie wydaje się lepszym rozwiązaniem niż opcja konfiguracji IDE. Nadal muszę coś zrobić dla wszystkich maszyna. – mattv

+0

Czy masz IDE skonfigurowane tak, aby łamać wszystkie wyjątki? – Kristen

Odpowiedz

1

Zawsze można użyć ExpectedExceptionAttribute (w NUnit), aby upewnić się, że jest to wyjątek zgłoszony. MSTest również ma podobne pojęcie.

[ExpectedException(typeof(MyException))] 
void my_test() 
{ 
    // test 
} 

Jeśli masz jakieś Mock weryfikację do zrobienia, chciałbym użyć try/catch i zweryfikować w połów, a następnie rzucić wyjątek.

UPDATE

Kiedy używasz atrybut ExpectedException, nie mają złapać wyjątek, a nie trzeba pozwolić NUnit, który uruchamia test, aby go złapać.

Jeśli trzeba zweryfikować specjalne informacje w wyjątku następnie złapać wyjątek, zweryfikować informacje, a następnie przekaż:

[ExpectedException(typeof(MyException))] 
void my_test() 
{ 
    try 
    { 
     // call the service 
    } 
    catch(MyException ex) 
    { 
      Assert.IsTrue(ex.Message.Contains("error code 200")); 
      throw ex; 
    } 

} 
+0

Aktualnie używam atrybutu ExpectedException w teście jednostki. Być może używam go niepoprawnie. Dodam, co robię w przykładowym kodzie. – mattv

+0

Zobacz moje aktualizacje. – Aliostad

+0

Cóż, dziękuję za poinformowanie mnie o właściwym używaniu tego atrybutu - nadal niestety nie rozwiązuje mojego problemu. Chociaż teraz test przechodzi, gdy wznawiam aplikację po jej złamaniu z powodu wyjątku! – mattv

1

mattv,

Dlaczego ten test ma dostęp do usługi zdalnie? Z tego, co widzę twój kod:

ResponseObject resp = GetServiceClient().DoSomething(req); 

W jakiś sposób dostaje klienta usług, a nie samą instancję usługi.Radziłbym przetestować klasę betonu serwisowego bezpośrednio na testy jednostkowe.

Jeśli jednak w tym scenariuszu potrzebujesz, czy próbowałeś NIE ZŁOŻYĆ wyjątku i przeprowadzić test? Czy daje ten sam rezultat?

A tak przy okazji, jeśli trzeba złapać i przekaż użyć następującego wzoru:

try { 
    //Do something 
} 
catch(SomeException e) { 
    //Do something with e 
    throw 
} 
+1

Ideą zdalnego dostępu do usługi jest przetestowanie niektórych funkcji skalowalności, które koncentrują się wokół klientów WCF, dlatego chcę mieć pokrycie testowe, w jaki sposób jest nawiązywane połączenie zdalne. Nie jestem pewien, czy jest to najlepszy sposób, naprawdę, ale lubię zasięg kodu ... Jeśli nie złapię wyjątku, test nie powiedzie się, co jest dokładne dla niektórych testów, ale w inni, naprawdę chciałbym przetestować, że błąd został zgłoszony. – mattv

Powiązane problemy