Search code examples
c#unit-testingeventsxunit

How to test if no event was invoked


I am new to UnitTests and therefore to Xunit. I have wrote some tests, but I am stuck with the testing of events.

Is it possible to test that no event was invoked with xunit?


I used this example for preparing my tests.

The first test works fine. For the second test, I expected something like 'Assert.RaisesNoEvent'; However, that method is not available.

Is there another way to test that no event was invoked?


Code Sample

Class where Event is Raised when Property2 is Set

public class Class 
{
    private int _property2;

    public event EventHandler RelevantPropertyChanged;
    public void OnRelevantPropertyChanged(EventArgs args){
        RelevantPropertyChanged?.Invoke(this, args);
    }

    public int Property1 { get; set; }
    public int Property2 { 
        get { return _property2; }
        set { 
            OnRelevantPropertyChanged(new EventArgs()); 
           _property2 = value; 
        } 
    }
}

TestClass defines unit tests for Class

public class TestClass 
{

    [Fact]
    public void ChangeProperty2_RaisesEvent() 
    {
        var cl = new Class();
        var args = new EventArgs();

        var evt = Assert.RaisesAny<EventArgs>(
            h => cl.RelevantPropertyChanged += h,
            h => cl.RelevantPropertyChanged -= h,
            () => cl.Property2 = 5);

        Assert.NotNull(evt);
        Assert.Equal(cl, evt.Sender);
        Assert.Equal(args, evt.Arguments);
    }

    [Fact]
    public void ChangeProperty1_RaisesNoEvent()
    {
        var cl = new Class();
        Action code = () => cl.Property1 = 5;

        Assert.RaisesNoEvent(code);          //this is what I want to do
    }
}

Solution

  • You can check that the event was not raised by checking that the EventHandler was not invoked:

    [Fact]
    public void ChangeProperty1_RaisesNoEvent()
    {
        var instance = new Class();
        bool isInvoked = false;
        instance.RelevantPropertyChanged += (s, e) => isInvoked = true;
    
        Assert.False(isInvoked);
        instance.Property1 = 5;
        Assert.False(isInvoked);
    }
    

    This technique works with any unit testing framework.