168 votes

Unité de tests qu’un événement est déclenché en c#

J'ai un code qui soulève PropertyChanged événements et je voudrais être en mesure de test de l'unité que les événements sont élevés correctement.

Le code qui est d'élever les événements, c'est comme

public class MyClass : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;  

   protected void NotifyPropertyChanged(String info)
   {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
   }  

   public string MyProperty
   {
       set
       {
           if (_myProperty != value)
           {
               _myProperty = value;
               NotifyPropertyChanged("MyProperty");
           }
       }
   }
}

Je reçois un joli vert d'essai à partir du code suivant dans mes tests unitaires, qui utilise des délégués:

[TestMethod]
public void Test_ThatMyEventIsRaised()
{
    string actual = null;
    MyClass myClass = new MyClass();

    myClass.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
    {
         actual = e.PropertyName;
    };

    myClass.MyProperty = "testing";
    Assert.IsNotNull(actual);
    Assert.AreEqual("MyProperty", actual);
}

Cependant, si je puis essayer de la chaîne et le réglage des propriétés de l'ensemble de la sorte:

public string MyProperty
{
    set
    {
        if (_myProperty != value)
        {
            _myProperty = value;
            NotifyPropertyChanged("MyProperty");
            MyOtherProperty = "SomeValue";
        }
    }
}

public string MyOtherProperty
{
    set
    {
        if (_myOtherProperty != value)
        {
            _myOtherProperty = value;
            NotifyPropertyChanged("MyOtherProperty");
        }
    }
}

Mon test pour le cas d'échec - l'événement qu'il capture est le cas pour la MyOtherProperty.

Je suis sûr que l'événement se déclenche, mon INTERFACE réagit comme il le fait, mais mon délégué ne capture de la dernière épreuve de feu.

Alors je me demandais:
1. Est ma méthode de dépistage correct?
2. Est ma méthode de collecte de enchaînés événements correct?

205voto

Andrew Stapleton Points 1108

Tout ce que vous avez fait est correct, offrant vous voulez que votre test de demander "Quel est le dernier événement qui a été soulevé?"

Votre code est de mettre le feu à ces deux événements, dans cet ordre

  • La Propriété A Changé (... "Ma Propriété" ...)
  • La Propriété A Changé (... "MyOtherProperty" ...)

Si c'est "correct" ou non dépend du but de ces événements.

Si vous voulez tester le nombre d'événements qui obtient augmenté, et l'ordre qu'ils sont très élevés, vous pouvez facilement étendre votre test existant:

[TestMethod]
public void Test_ThatMyEventIsRaised()
{
    List<string> receivedEvents = new List<string>();
    MyClass myClass = new MyClass();

    myClass.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
    {
        receivedEvents.Add(e.PropertyName);
    };

    myClass.MyProperty = "testing";
    Assert.AreEqual(2, receivedEvents.Count);
    Assert.AreEqual("MyProperty", receivedEvents[0]);
    Assert.AreEqual("MyOtherProperty", receivedEvents[1]);
}

22voto

Tim Lloyd Points 23571

Si vous êtes en train de faire TDD événement tests peuvent commencer à générer un beaucoup de code répétitif. J'ai écrit un moniteur d'événement qui permet à un beaucoup plus propre approche de test de l'unité de l'écriture de ces situations.

var publisher = new PropertyChangedEventPublisher();

Action test = () =>
{
    publisher.X = 1;
    publisher.Y = 2;
};

var expectedSequence = new[] { "X", "Y" };

EventMonitor.Assert(test, publisher, expectedSequence);

Veuillez voir ma réponse à la suite pour plus de détails.

http://stackoverflow.com/questions/2567047/unit-testing-that-an-event-is-raised-in-c-using-reflection/2697721#2697721

Ou d'une série d'articles de blog, j'ai posté à ce sujet:

http://gojisoft.com/blog/2010/04/22/event-sequence-unit-testing-part-1/

11voto

Samuel Points 2327

C’est très ancienne et probablement ne sera pas même être lu, mais avec quelques fonctionnalités nouvelles de .net, j’ai créé une classe INPC traceur qui permet cela :

Voir l’essentiel : https://gist.github.com/Seikilos/6224204

6voto

Damir Arh Points 9119

Ci-dessous est code d’un Andrew légèrement différente qui à la place de la coupe juste que la séquence des événements surélevés compte plutôt comment beaucoup de fois un événement spécifique a été appelé. Bien qu’il est basé sur son code je trouve plus utile lors de mes tests.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X