Wat is mocking?

Mocking is een techniek in software testing waarmee je objecten of componenten simuleert om gecontroleerde testomgevingen te creëren. Het stelt ontwikkelaars in staat om de afhankelijkheden van een systeem te isoleren en het gedrag van specifieke methoden of interfaces te definiëren zonder de daadwerkelijke implementatie aan te roepen. Dit is nuttig om de logica van een systeem te testen zonder de werking van externe componenten te verstoren.

Casus

Stel je hebt een e-commerce applicatie waarin een service PaymentService betalingen verwerkt. Tijdens het testen wil je voorkomen dat er echte transacties worden uitgevoerd. Je kunt een mock maken van PaymentService die een gesimuleerde reactie retourneert zoals ‘Betaling geslaagd’.

Hoe zit mocking in elkaar?

Bij mocking worden testdoubles, zoals mocks of stubs, gebruikt om afhankelijkheden te vervangen. Dit zorgt ervoor dat tests betrouwbaar en onafhankelijk blijven. Testdoubles zijn objecten die zich gedragen als echte afhankelijkheden, maar met gecontroleerd gedrag. Er zijn verschillende soorten testdoubles, waaronder stubs, die vooraf gedefinieerde antwoorden geven, en mocks, die interacties kunnen verifiëren.

Een veelgebruikt mocking-framework is Moq, waarmee eenvoudig testdoubles kunnen worden gemaakt en geconfigureerd. Meer uitleg over testdoubles is te vinden in Martin Fowler’s artikel.

Codevoorbeeld

In dit voorbeeld wordt IPaymentService gemockt met behulp van Moq. De ProcessPayment-methode retourneert altijd de string “Betaling geslaagd”, ongeacht de invoer.

using Moq;
 
// Interface voor de service
public interface IPaymentService {
    string ProcessPayment(decimal amount);
}
 
// Mock aanmaken
var paymentServiceMock = new Mock<IPaymentService>();
 
// Gedrag definiëren
paymentServiceMock.Setup(p => p.ProcessPayment(It.IsAny<decimal>())).Returns("Betaling geslaagd");
 
// Mock gebruiken
var result = paymentServiceMock.Object.ProcessPayment(100m);
Console.WriteLine(result); // Output: Betaling geslaagd

Hoe gebruik je mocking?

Mocking wordt gebruikt wanneer:

  • Externe afhankelijkheden onvoorspelbaar gedrag vertonen (bijv. API-calls).
  • Een testomgeving gecontroleerd moet worden zonder bijwerkingen.
  • Er bepaalde scenario’s gesimuleerd moeten worden, zoals fouten of timeouts.

Casus

Een applicatie gebruikt een UserService om gebruikersgegevens op te halen uit een externe database. Je wilt testen hoe de applicatie reageert als de database geen gegevens retourneert.

Mogelijke uitwerking van de casus In dit voorbeeld wordt gesimuleerd dat een gebruiker met ID 99 niet bestaat.

using Moq;
 
public interface IUserService {
    string GetUserById(int id);
}
 
var userServiceMock = new Mock<IUserService>();
 
// Definieer gedrag voor een niet-bestaande gebruiker
userServiceMock.Setup(u => u.GetUserById(99)).Returns((string)null);
 
var result = userServiceMock.Object.GetUserById(99);
Console.WriteLine(result == null ? "Gebruiker niet gevonden" : result);

Bronnen

Moq: https://github.com/devlooped/moq?tab=readme-ov-file#readme Testdoubles: https://martinfowler.com/bliki/TestDouble.html


Volgende stap: Stappen Mocking