5

The following code compiles, runs, does exactly what I'm expecting - the GreetingPublisher calls bus.Publish() when the event is raised - but the Moq setup isn't being matched:

using Moq;
using NServiceBus;
using NUnit.Framework;

namespace MyProject.Greetifier.Tests {
    [TestFixture]
    public class GreetingPublisher_Bus_Integration_Tests {
        [Test]
        public void Greeting_Is_Published_To_Bus() {
            var mockGreeter = new Mock<IGreeter>();
            var mockBus = new Mock<IBus>();
            mockBus.Setup(bus => bus.Publish<IMessage>(It.IsAny<IMessage>()))
                   .Verifiable();
            var Greetifier = new GreetingPublisher(mockGreeter.Object,
                                                   mockBus.Object);
            mockGreeter.Raise(m => m.Greet += null, "world");
            mockBus.Verify();
        }
    }

    public class HelloMessage : IMessage {
        public string Name { get; set; }
        public HelloMessage(string name) { this.Name = name; }

    }

    public class GreetingPublisher {
        private readonly IGreeter greeter;
        private readonly IBus bus;

        public GreetingPublisher(IGreeter greeter, IBus bus) {
            this.greeter = greeter;
            greeter.Greet += handleGreetEvent;
            this.bus = bus;
        }

        void handleGreetEvent(string name) {
            bus.Publish(new HelloMessage(name));
        }
    }

    public delegate void GreetingEvent(string name);

    public interface IGreeter {
        event GreetingEvent Greet;
    }
}

and when running the test, I get:

Test 'MyProject.Greetifier.Tests.GreetingPublisher_Bus_Integration_Tests.Greeting_Is_Published_To_Bus' failed:
Moq.MockVerificationException : The following setups were not matched:
IBus bus => bus.Publish<IMessage>(new[] { It.IsAny<IMessage>() })
at Moq.Mock.Verify()
D:\Projects\MyProject\src\MyProject.Greetifier.Tests\Program.cs(15,0): MyProject.Greetifier.Tests.GreetingPublisher_Bus_Integration_Tests.Greeting_Is_Published_To_Bus()

Am I missing something obvious?

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
Dylan Beattie
  • 53,688
  • 35
  • 128
  • 197

1 Answers1

6

If I see it correctly, your code calls IBus.Publish<HelloMessage> and not IBus.Publish<IMessage>.

(EDIT: I replaced

mockBus.Setup(bus => bus.Publish<IMessage>(It.IsAny<IMessage>()))
               .Verifiable();

with:

mockBus.Setup(bus => bus.Publish<HelloMessage>(It.IsAny<HelloMessage>()))
               .Verifiable();

and it works as expected - Dylan)

Dylan Beattie
  • 53,688
  • 35
  • 128
  • 197
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Ah... I hadn't realised that It.IsAny wouldn't match classes that implement T... thanks! – Dylan Beattie Jul 20 '11 at 13:05
  • I'm currently dealing with this issue. `It.IsAny()` _does_ match a generic interface to a concrete implementation in Moq when _not_ mocking `NServiceBus.IBus`, and even behaves as expected for arrays of generic interface types (such as is specified in the `IBus.Publish` method), but for some reason fails when mocking `IBus`. This appears to have something to do with confusion over specific types, possibly stemming from NServiceBus's handling of messages as interfaces via concrete proxies, although why it needs to do this on Publish currently eludes me. – sennett Feb 27 '13 at 22:46
  • @sennett: I suggest you post a new question for this with some sample code. That will make it easier to help you. – Daniel Hilgarth Feb 27 '13 at 23:33
  • @daniel Cheers. Just finished asking it. http://stackoverflow.com/q/15124934/614523 – sennett Feb 27 '13 at 23:59