views:

198

answers:

2

I have an object that gets passed into a method as a parameter. This object has a event on it which should get subscribed to when I call this method with the object as the argument.

Does NUnit allow me to check this?

Edit: Added a code sample:

    [Test]
    public void AddingToCollectionShouldHookPropertyChangedEventUp()
    {
        // Arrange:
        var viewModel = new viewModel();
        var viewModelCollection = new viewModelCollection();

        // Act:
        viewModelCollection.AddViewModel(viewModel);

        // Assert that the property changed event is hooked up in some way:
        // This is commented out because I cannot do this. I left it here to  
        // illustrate what I want to achieve:
        //blockViewModel.PropertyChanged.Should().Not.Be.Null();
    }
A: 

You can just check if the event is null. If it has subscribers, then it will not be null.

zaph0d
can you show code that does this? Something like "Assert.That(_vm.Workspaces.CollectionChanged, Is.Not.Null);" won't get past the compiler since the "event can only appear on the left hand side of += or -=". Cheers
Berryl
This is false. You cannot get an invocation list from outside the scope of the class itself.
Corpsekicker
+2  A: 

You cannot get at the state of an event; by design you can only register to it += or unregister -= from it. Because of this, there is no extension or other mechanism that NUnit provides to test the event has been subscribed to.

If the event is on an interface, you can test subscription via a mock class (either your own or a framework's mock, like Rhino).

You can of course test the behavior of the event, in any event!

If you post some code I'm sure someone will help you come up with a meaningful test. Here's a sample dummy one to give you some ideas:

[Test]
public void ChangingTheWhateverProperty_TriggersPropertyChange()
    {

        // Create anonymous delegate which is also your test assertion
        PropertyChangedEventHandler anonymousDelegate = (sender, e) => Assert.AreEqual("Whatever", e.PropertyName);

        // Subscribe to the needed event
        vm.PropertyChanged += anonymousDelegate;

        // trigger the event
        vm.Whatever = "blah";
    }

HTH,
Berryl

=== modified example with your code =======

[Test]
    public void AddingToCollectionShouldHookPropertyChangedEventUp()
    {
        // Arrange: 
        var viewModel = new viewModel();
        var viewModelCollection = new viewModelCollection();

        // This *IS* your assert also, and will get called back when you Act
        // The only part you need to supply for this test is the property that gets fired when you add a viewmodel
        PropertyChangedEventHandler anonymousDelegate = (sender, e) => Assert.AreEqual("Whatever", e.PropertyName);

        // Subscribe to the needed event 
        viewModelCollection.PropertyChanged += anonymousDelegate;

        // Act: 
        viewModelCollection.AddViewModel(viewModel);
    }

=== example rhino test for event registration =====

   [Test]
    public void Test()
    {
        var mockCorpseKicker = MockRepository.GenerateMock<INotifyPropertyChanged>();
        mockCorpseKicker.PropertyChanged += null;
        mockCorpseKicker.AssertWasCalled(x => x.PropertyChanged += Arg<PropertyChangedEventHandler>.Is.Anything);
    }
Berryl
I've been trying to avoid using a mocking framework, but if this is the only way, I should rethink that. Thanks for the reply.
Corpsekicker
But you DON'T need a mock frameowrk to test that adding a viewmodel to the viewmodelcollection fires your property change. I ammended my dummy test case a bit to highlight this, but I don't know from what you've posted WHICH property you want to fire. Substitute the property name in my test and you will have a working test that proves the wiring is correct.
Berryl
I'm not trying to assert that anything gets fired. I'm trying to assert that an event is subscribed to. In other words, I want to ensure that in my AddViewModel(ViewModel viewModelToAdd) method there is a line that says viewModelToAdd.PropertyChanged += PropertyChangedHandler;
Corpsekicker
Ok corpeskicker, see the latest code addition, wihich lierally does what you want using RhinoMocks. If the event was not set, the test fails; if it was set to anything including null then the test passes. Why do you kick corpes anyway?? Cheers
Berryl
Berryl, you're a rockstar. var blockViewModel = MockRepository.GenerateMock<IBlockViewModel>(); var blockViewModelCollection = new BlockViewModelCollection(); blockViewModelCollection.AddViewModel(blockViewModel); blockViewModel.AssertWasCalled(x => x.PropertyChanged += Arg<PropertyChangedEventHandler>.Is.Anything);
Corpsekicker
And I would never kick your corpse. Just the corpse of this question :)
Corpsekicker