Jestem nowy w Kpiącym i trochę obeznanym z testowaniem jednostkowym i ostatecznie zdecydowałem się ugryźć bullet na nowym projekcie rozpoczynającym się od przodu z surowym podejściem TDD. Mam jednak jedną klasę usług i metodę, którą muszę retrospektywnie dodać do testów, ponieważ została ona wypromowana z prototypu.Usługa Testu Jednostek, która ma wywołanie WCF (MSUnit + Moq)
nie wiem od czego zacząć, choć na tym konkretnym teście, to klasy i metody zaangażowany:
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;
}
}
Co Usiłuję zrobić, to napisać jeden test, z tym mam nadzieję, że mogę rozwijać wszystkie permutacje z testów GetPage(...)
, ale dla pierwszego testu wystarczy przetestować, czy poprawne websiteId
i pageKey
zostało przekazane, jeśli tak, otrzymają prawidłową instancję z powrotem i potwierdzą prawdziwość testu jednostkowego.
testServiceClient
jest klientem usługi WCF, który był wcześniej zawarty w oświadczeniu using()
, ale usunąłem go z tego, mając nadzieję, że będzie to działało z zastrzykiem zależności, ponieważ uważam, że będzie to pierwszy krok wymagany do testowania, z tego, co rozumiem, będę musiał zrobić z niego fałszywkę/wyśmiać? klient wcf zamiast, gdzie testServiceClient.GetPage()
zwraca znany zestaw danych w pamięci? Mam nadzieję, że jestem na dobrej drodze.
Więc tutaj jest moje początkowe plany mojego testów jednostkowych (Używam Moq ramy, Setup()
jest nowa wersja Expect()
jeśli nie wykorzystali najnowszą ver z Min):
/// <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.");
}
ja nie mam pomysł, dokąd się udać, czy jestem na dobrej drodze? Mogę potwierdzić powyższe nie ma błędów składniowych, a ja nie otrzyma wyjątek:
System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetPage(websiteId, "about-us").
Wiem tylko, że chcę moje service.GetPage(...)
zwrócić nową instancję, jak websiteId
i pageKey
była ważna, jednak I don” Chcę używać prawdziwego wywołania WCF testServiceClient.GetPage()
... mam nadzieję, że rozumiem ideę kpiny poprawnie. Czy powiedziałem to poprawnie poprzez Moq, gdy używasz usługi testServiceClient.GetPage
w tej usłudze, w rzeczywistości po prostu zwracasz nową instancję strony?
Wszelkie wyjaśnienia są mile widziane! Dzięki chłopaki!
+1 Dobra odpowiedź - @GONeale, tylko po to, aby potwierdzić, co mówi Mark, przeprowadziłem szybki test za pomocą MOQ i interfejsu, który zwraca stronę - działa dobrze. Wydaje się, że zamiast tego robisz coś takiego, jak mockowanie konkretnej instancji, w której GetPage nie jest deklarowane jako wirtualne. –
Cześć chłopaki, dziękuję za poświęcenie czasu na przeczytanie mojego posta. Cóż, ITestService jest klientem usługi generowanej przez WCF (projekt prawym przyciskiem myszy -> dodaj nazwę referencyjną usługi). W związku z tym nie sądzę, że mogę zadeklarować go jako "wirtualny", ponieważ jest to klasa generowana automatycznie. Mógłbym jednak stworzyć prostą klasę wywołującą WCF i uczynić ją wirtualną, czy mogłoby to pomóc w twoim przypadku? Dzięki za wskazówkę Assert. – GONeale
Czy rozumiem poprawnie mówiąc przez deklarowanie 'testServiceClient.Setup (x => x.GetPage (..)). Zwroty (newPage)' mówi każde wywołanie nazwy tej metody (zagnieżdżone nawet jako metoda obiektu przekazywana przez jako parametr, taki jak przykład 'new PageService (testServiceClient.Object)'), aby faktycznie nie uruchomić metody * actual * (wcf), ale po prostu zwrócić instancję 'newPage' zamiast tego? Czy właśnie dlatego 'virtual' jest wymagany, zastępuje go całkowicie nową zawartością metody? – GONeale