2012-01-30 13 views
7

ile bir komut ve olay tabanlı sistem nasıl test edilir Bir yürütme işlemi gerçekleştirildiğinde bir olayı tetikleyen bir etki alanı nesnesindeki bir işlemi başlatır bir komut işleyicisine sahibim. Bir olay işleyicisinin, ilgili komut gönderildiğinde olayı aldığını test etmek isterim (aşağıya bakınız, bazı kodlar kısırlık için atlanmıştır). Olay iletisi veri yolu üzerinde yayınlanmış olsa bile olay işleyicisi (MyEventConsumer.Consume) hiçbir zaman çağrılmaz (bu durumda geridönüş yolu). Herhangi bir fikir?Masstransit

//Test 
[TestFixture] 
public class TestSendCommandReceiveEvent 
{ 
    [Given] 
    public void installation_of_infrastructure_objects() 
    { 
     container.Register(Component.For<MyEventConsumer>().UsingFactoryMethod(() => new MyEventConsumer(_received))); 
     container.Register(
     Component.For<IServiceBus>() 
     .UsingFactoryMethod(() => ServiceBusFactory.New(x => { x.ReceiveFrom("loopback://localhost/mt_client"); x.Subscribe(conf => conf.LoadFrom(container));              }))); 
    } 

    [When] 
    public void sending_a_command() 
    { 
     var LocalBus = container.Resolve<IServiceBus>(); 
     LocalBus.Publish(new DoSomething(_aggregateId)); 
    } 
    [Then] 
    public void corresponding_event_should_be_received_by_consumer() 
    { 
     _received.WaitOne(5000).ShouldBeTrue(); 
    } 
} 
public class MyEventConsumer : Consumes<SomethingDone>.All 
{ 
    private readonly ManualResetEvent _received; 
    public MyEventConsumer(ManualResetEvent received) 
    { 
     _received = received; 
    } 
    public void Consume(SomethingDone message) 
    { 
     _received.Set(); 
    } 
} 

//Command handler 
public class DoSomethingCommandHandler : Consumes<DoSomething>.All where T:class 
{ 
    public void Consume(DoSomething message) 
    { 
     var ar = Repository.GetById<SomeAR>(message.ArId); 
     ar.DoSomething(); 
     Repository.Save(ar, Guid.NewGuid(), null); 
    } 
} 
//Domain object 
public class SomeDomainObject : AggregateBase 
{ 
    public void DoSomething() 
    { 
     RaiseEvent(new SomethingDone(Id, 1)); 
    } 
} 
+0

üretimde bu çalışıyor mu ve sadece bir testte başarısız? Öyle görünüyor ki, koddan her şey yolunda görünüyor, ama sanırım kodda bazı hatalar var, yani bu şeylerin doğru bağlandığını varsayıyor. Ne yazdığın hakkında biraz daha ayrıntılı bir şekilde posta listesine katılmayı öneririm. https://groups.google.com/forum/#!forum/masstransit-discuss Tahmin etmem gerekirse, belki de konteynerle ilgili bir sorun. Sanırım hepsini çözdük ama bir aykırı olabilir. – Travis

+0

Hmm, bir üretim konusu gibi görünüyor. Veriyolu yanlış yapılandırılmış olmalı. Bir göz atacağım. – Christian

+0

Tamam, burada ne eksik olduğunu göremiyorum (MT/Kale ile kendi deneyim eksikliği hariç). Mail listesine geçiyorum. – Christian

cevap

5

Bu benim için geçer:

// Copyright 2012 Henrik Feldt 
// 
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use 
// this file except in compliance with the License. You may obtain a copy of the 
// License at 
// 
//  http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software distributed 
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
// specific language governing permissions and limitations under the License. 

using System; 
using System.Threading; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 
using Magnum.Extensions; 
using Magnum.TestFramework; 
using MassTransit; 
using NUnit.Framework; 

namespace ConsoleApplication11 
{ 
    [TestFixture] 
    public class TestSendCommandReceiveEvent 
    { 
     ManualResetEventSlim _received = new ManualResetEventSlim(false); 
     IWindsorContainer _container; 

     [Given] 
     public void installation_of_infrastructure_objects() 
     { 
      _container = new WindsorContainer(); 
      _container.Register(
       Component.For<IServiceBus>() 
        .UsingFactoryMethod(() => ServiceBusFactory.New(x => 
         { 
          x.ReceiveFrom("loopback://localhost/mt_client"); 
          x.Subscribe(conf => 
           { 
            conf.Consumer(() => new MyEventConsumer(_received)); 
            conf.Consumer(() => new MyCmdConsumer()); 
           }); 
         }))); 

      when(); 
     } 

     public void when() 
     { 
      var localBus = _container.Resolve<IServiceBus>(); 
      // wait for startup 
      localBus.Endpoint.InboundTransport.Receive(c1 => c2 => { }, 1.Milliseconds()); 

      localBus.Publish(new DoSomething()); 
     } 

     [Then] 
     public void corresponding_event_should_be_received_by_consumer() 
     { 
      _received.Wait(5000).ShouldBeTrue(); 
     } 
    } 

    [Serializable] 
    public class DoSomething 
    { 
    } 

    [Serializable] 
    public class SomethingDone 
    { 
    } 

    public class MyEventConsumer : Consumes<SomethingDone>.All 
    { 
     readonly ManualResetEventSlim _received; 

     public MyEventConsumer(ManualResetEventSlim received) 
     { 
      _received = received; 
     } 

     public void Consume(SomethingDone message) 
     { 
      _received.Set(); 
     } 
    } 

    public class MyCmdConsumer : Consumes<DoSomething>.Context 
    { 
     public void Consume(IConsumeContext<DoSomething> ctx) 
     { 
      Console.WriteLine("consumed cmd"); 
      ctx.Bus.Publish(new SomethingDone()); 
     } 
    } 
} 
0

Tecrübemde, herhangi bir yayınlanan iletinin kaybolduğu otobüs örneğinin oluşturulmasının hemen ardından kısa bir süre var. Bir çeşit async başlatma işlemi olmalı.

container.Resolve<IServiceBus>() ve LocalBus.Publish(new DoSomething(_aggregateId)) arasında bir gecikme eklemeye çalışın.

Thread.Sleep benim durumumda çalışmadı, ama bir Console.ReadLine() şaşırtıcı bir şekilde yaptı!

+4

Şunları yapabilirsiniz: 'bus.Endpoint.InboundTransport.Receive (c1 => c2 => {}, TimeSpan.FromMilliseconds (1));' Thread.Sleep yerine. Sorun, gelen ve nakil alma/gönderme döngülerinin asenkronize olarak başlatılmış olmasıdır. – Henrik