2015-11-15 22 views
16

Nie mogę przetestować niezawodnej usługi/aktora, po prostu wywołując jego konstruktor, a następnie przetestować jego metody. var testService = new SomeService(); zgłasza wyjątek NullReferenceException. Więc co mogę zrobić z wdrożoną usługą?Testowanie jednostki usługowej i iniekcja zależności

Rozumiem, że wdrożone SF Reliable Services/Actors nie są standardowymi klasami .NET, a testowanie jednostkowe wdrożonego S/A może być dziwnym pomysłem.

W każdym razie teraz próbuję spróbować.

Na przykład. Właśnie wdrożyłem usługę, niż w teście, w którym utworzyłem obiekt Proxy i dodałem element do kolejki wejściowej Usługi. Następnie muszę potwierdzić, że licznik kolejki wejściowej = 1. Działa to, gdy właśnie wdrożyłem Usługę i żaden inny Klient/Usługi/Aktorzy nie użyli jej kolejki wejściowej. Ale następnym razem ten test się nie powiedzie, to jest problem. Muszę sprawić, aby Usługa przestała działać z innymi klientami, odrzucić kolejkę i przetestować ją. W tym celu mogę utworzyć właściwość TestMode i niektóre metody, takie jak PropareoForTests/TestingCompleted i wywołać je z klienta testowego przed i po testowaniu.

Czy to jest zły pomysł, aby to zrobić w ten sposób. Może są jakieś wytyczne dotyczące testowania jednostkowego SF? Dzięki.

UPDATE:

Badając Service Fabric Web Reference Application example Znalazłem ten ciąg TODO:

/// TODO: Temporary property-injection for an IServiceProxyWrapper until constructor injection is available. 

to znaczy, że SF Usługi poprawi To wsparcie DI? A co z aktorami?

+3

Zastrzyk zależności od konstruktorów jest obecnie dostępny w aktorze! Kiedy rejestrujesz swój typ aktora, możesz także zarejestrować "fabrykę", która jest w rzeczywistości Func <>, gdzie tworzysz instancję klasy Aktor, która daje ci kontrolę nad instancją Aktora, dzięki czemu możesz tam wstrzykiwać zależności. W usługach możesz już to zrobić, sprawdź, jak to robimy w przykładowym klastrze Party: https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster/tree/master/PartyCluster/ ClusterService –

+1

Napisałem odpowiedź na temat wykonywania wtyczki zależności z jednością: http://stackoverflow.com/questions/30384780/azure-service-fabric-actor-dependency-injection/35900027#35900027 –

+0

@VaclavTurecek Twój link jest zepsuty – Dismissile

Odpowiedz

16

W rzeczywistości można przetestować niezawodne usługi i aktorów w taki sam sposób, jak w przypadku innych klas w .NET! Są one szczególne tylko dlatego, że używają pewnych haczyków do podstawowej platformy, ale poza tym można utworzyć instancję klasy lub normalnie i wywołać na niej metody.

Obecnie niezawodne usługi są nieco łatwiejsze do testowania jednostkowego, ponieważ podstawowy interfejs do platformy, State Manager, to interfejs, który można podłączyć przez konstruktor.

Na przykład klasa usług może wyglądać następująco:

EDIT: Aktualizacja z API GA uwalnianiu (2.0.135)

class MyService : StatefulService 
{ 
    public MyService (StatefulServiceContext context, IReliableStateManager stateManager) 
     :base (context, stateManager) 
    { 
    } 

    public void MyMethod() 
    { 
    // do stuff.. 
    } 
} 

Następnie można przetestować swoją klasę usług tak:

[TestMethod] 
public TestMyMethod() 
{ 
    MockReliableStateManager stateManager = new MockReliableStateManager(); 
    MyService target = new MyService(stateManager); 

    target.MyMethod(); 
    // validate results and all that good stuff 
} 

Mamy pełną przykład pracę rzeczywistych usług z wieloma zależnościami jednostka badana dostępny na GitHub: https://github.com/Azure-Samples/service-fabric-dotnet-management-party-cluster

W tym przykładzie IReliableStateManager i IReliableDictionary kpi również z tego, że możesz użyć ich jako punktu wyjścia do własnych testów jednostkowych.

+0

Dzięki, Vaclav! Dokładnie to jest potrzebne. Proszę spojrzeć na aktualizację. – AsValeO

+1

W RTM (Actors 2.0.135) własność 'Actor.StateManager' jest tylko do odczytu (brak' zestawu chronionego'). W jaki sposób mam wstrzyknąć zależność menedżera stanu dla mojej klasy aktorów? –

+0

A co z przypomnieniami i zegarami dla aktorów? Mogę samodzielnie wywołać metodę 'ReceiveReminderAsync', ale muszę zweryfikować wywołania wykonywane na' RegisterReminderAsync' (metoda chroniona na 'ActorBase'). –

4

dla wyśmianie kierownika państwowej w wiarygodnych aktorów, można zrobić coś takiego:

private readonly IActorStateManager _stateManager; 

public MyActor(IActorStateManager stateManager = null) 
{ 
    _stateManager = stateManager ?? this.StateManager; 
} 

Właściwie StateManager nie jest jeszcze zainicjowany w tym czasie. Możemy go kiedy OnActivateAsync nazywa się:

private IActorStateManager _stateManager; 

// Unit tests can inject mock here. 
public MyActor(IActorStateManager stateManager = null) 
{ 
    _stateManager = stateManager; 
} 

protected override async Task OnActivateAsync() 
{ 
    if (_stateManager == null) 
    { 
     _stateManager = StateManager; 
    } 
} 

Wystarczy upewnić się, aby zawsze używać _stateManager w pozostałej części kodu zamiast this.StateManager.