2009-08-28 8 views
0

J'écris un test unitaire pour savoir quand mon ordinateur reçoit/passe un appel téléphonique.Tests unitaires avec les états informatiques

Les méthodes testées sont les événements qui gèrent l'appel entrant/sortant. Si l'appelant n'est pas un appelant approuvé, l'appel est rejeté.

Le code fonctionne bien, mais je ne peux pas vraiment trouver quelque chose à tester pour mon test unitaire. Le problème est que l'état actuel de "si mon ordinateur est dans un appel ou non" est pas contrôlé par ma classe. Seul l'ordinateur sait si un appel est actuellement connecté ou non. Je souhaite qu'il y ait un certain Guru Unit Test là-bas que peut me dire quoi faire pour tester ce scénario. Je ne veux pas créer un var dummy qui n'a aucun rapport avec mon code juste pour faire passer mon test d'unité.

Pour faire cela un peu plus concret, voici mon test unitaire:

private DeviceMediator deviceMediator; 
    private IDeviceControlForm deviceControlForm; 
    private IDataAccess data; 
    private ICallMonitor callMonitor; 

    // Use TestInitialize to run code before running each test 
    [TestInitialize()] 
    public void MyTestInitialize() 
    { 
     deviceControlForm = MockRepository.GenerateStub<IDeviceControlForm>();   
     data = MockRepository.GenerateStub<IDataAccess>(); 
     callMonitor = MockRepository.GenerateStub<ICallMonitor>(); 

     deviceMediator = new DeviceMediator(deviceControlForm, data) 
      {CallMonitor = callMonitor}; 
    } 

    [TestMethod] 
    public void TestHandleIncomingCall() 
    { 
     //Arrange 

     //Act 
     deviceMediator.OnIncomingCall(null, new CallState(), 
      new CallInfoState()); 

     //Assert 
     // I could not find anything to feasably test on this. 
     Assert.IsTrue(true); 
    } 

et est ici la méthode qu'il appelle:

public void OnIncomingCall(Call call, CallState callState, 
    CallInfoState callInfoState) 
{ 
    // See if this call is on our list of approved callers 
    bool callApproved = false; 
    foreach (PhoneContact phoneContact in Whitelist) 
    { 
     if (phoneContact.PhoneNumber == call.CallerID) 
      callApproved = true; 
    } 

    // If this is not an approved call then 
    if (!callApproved) 
     CallMonitor.Hangup(); 
} 
+0

Pouvez-vous préciser ce que votre appel, les cours CallState et CallInfoState faire? – bryanbcook

+0

Dans ce cas, ils ne font rien. Lors d'un appel réel, ils auraient l'information d'appel et l'appel. Je les utilise pour obtenir le numéro de l'appelant actuel (que je viens de réaliser, je ne me nourris pas dans mon test d'unité). Ils ne sont lus par rien d'autre, donc je ne pouvais pas les utiliser pour récupérer une valeur (et ils ne sont pas transmis par référence) – Vaccano

Répondre

2

Il s'avère que je n'en savais pas assez sur Rhino Mocks. La réponse à ce problème peut être trouvée here.

Ceci est mon code avec cette réponse incorporée.

test unitaire:

[TestMethod] 
    public void TestHandleIncomingCall() 
    { 
     //Arrange 
     callMonitor.InCall = true; 
     // This is the magic. When Hangup is called I am able to set 
     // the stub's InCall value to false. 
     callMonitor.Expect(x => x.Hangup()).Callback(() => WhenCalled(invocation => 
                 { 
                  callMonitor.InCall = false; 
                 }); 
     List<PhoneContact> whiteList = FillTestObjects.GetSingleEntryWhiteList(); 
     data.Expect(x => x.GetWhiteListData()).Return(whiteList); 
     const string invalidPhoneNumber = "123"; 

     //Act 
     deviceMediator.HandleIncomingCall(invalidPhoneNumber); 

     //Assert 
     Assert.IsFalse(callMonitor.InCall); 
    } 

je devais changer mon code pour cela parce appel a un constructeur interne:

public void OnIncomingCall(Call call, CallState callState, 
     CallInfoState callInfoState) 
    { 
     // See if this call is on our list of approved callers 
     HandleIncomingCall(call.CallerID); 
    } 

    public void HandleIncomingCall(string callNumber) 
    { 
     bool callApproved = false; 
     foreach (PhoneContact phoneContact in Whitelist) 
     { 
      if (phoneContact.PhoneNumber == callNumber) 
       callApproved = true; 
     } 

     // If this is not an approved call then 
     if (!callApproved) 
      CallMonitor.Hangup(); 
    } 
0

Voici un couple de choses que vous pourriez faire:

  1. Vous pouvez créer une collection WhiteList fictive qui contiendra un certain ensemble de PhoneContacts, puis appeler OnIncomingCall avec Pho neContacts qui sont ou ne sont pas dans la liste blanche, puis vérifiez le CallMonitor (ou l'objet Call lui-même, je suppose) pour voir si l'appel est dans l'état correct. Donc Assert.IsTrue (call.IsConnected) ou Assert.IsFalse (call.IsConnected) selon le scénario que vous testez.
  2. Vous pouvez également voir si la méthode gère les objets d'appel qui sont NULL ou qui ne sont pas dans l'état correct au moment où cette méthode est appelée.
1

Cela s'appelle l'injection de dépendances. Vous faites agir votre code sur une interface qui imite la véritable API du téléphone, et fournissez votre propre implémentation contrôlable pour les tests. Il y a des systèmes comme Spring.Net qui rendent cela plus facile à faire.