测试从测试演员

时间:2016-02-12 16:29:21

标签: akka.net

我试图测试从测试的actor发送的消息,但是获得超时异常和死信信息。 当我使用ninject时 - 创建了一个模拟方法,它始终使用探测器actor引用进行重放。 我在这里错过了什么吗?

        Assert.Fail failed. Failed: Timeout 00:00:03 while waiting for a message of type System.Type 
       at Akka.TestKit.TestKitBase.InternalExpectMsgEnvelope(Nullable`1 timeout, Action`2 assert, String hint, Boolean shouldLog)
       at Akka.TestKit.TestKitBase.InternalExpectMsgEnvelope(Nullable`1 timeout, Action`1 msgAssert, Action`1 senderAssert, String hint)
       at Akka.TestKit.TestKitBase.InternalExpectMsg(Nullable`1 timeout, Action`1 msgAssert, String hint)
       at Akka.TestKit.TestKitBase.ExpectMsg(T message, Nullable`1 timeout, String hint)
       at 
     

AutoApply.UnitTests.SomethingProcessorActors.SomethingProcessorActorTests.SomethingProcessorActorWhenMergeDataAndGetsNoProfilesLogsThat()   在SomethingProcessorActorTests.cs中:第58行

    [WARNING][12/02/2016 16:12:43][Thread 0009][akka://test/user/testProbe] DeadLetter from [akka://test/temp/d]
     

到[akka:// test / user / testProbe]:           [INFO] [12/02/2016 16:12:43] [Thread 0011] [akka:// test / user / testProbe]消息   从akka:// test / temp / d到GetOneSomethingAndRemoveFromList   akka:// test / user / testProbe未送达。 1封死信   遇到。           调试跟踪:           设置探针参考:akka:// test / user / testProbe           GetDataActorPath for:SomethingsDataActor           GetDataActorPath => akka:// test / user / testProbe           GetDataActorPath for:SomethingCollectorActor           GetDataActorPath => akka:// test / user / testProbe

    [TestClass]
    public class SomethingProcessorActorTests : TestKit
    {
        /// <summary>The factory helper</summary>
        private IMockingExtension factoryHelper;

        private TestProbe probeActorRef;

        /// <summary>Configurations this instance.</summary>
        [TestInitialize]
        public void Config()
        {

            this.probeActorRef = this.CreateTestProbe("testProbe");
            this.factoryHelper = new MockingFactoryHelper();
            this.factoryHelper.SetProbe(this.probeActorRef.TestActor);
        }

        /// <summary>Somethings the processor actor when merge data and gets no profiles logs that.</summary>
        [TestMethod]
        public void SomethingProcessorActorWhenMergeDataAndGetsNoProfilesLogsThat()
        {
            // arrange
            var actor =
                this.Sys.ActorOf(
                    Props.Create(() => new SomethingProcessorActor(this.factoryHelper as IActorPathAndFactory)),
                    "SomethingActor");

            // act
            actor.Tell(new SomethingProcessorActor.ProcessSomethings());

            // assert
            this.probeActorRef.ExpectMsgFrom<SomethingsDataActor.GetOneSomethingAndRemoveFromList>(actor, new TimeSpan(0, 0, 0, 5));

        }
    }
    =======================
 public partial class SomethingProcessorActor : ReceiveActor
{
    /// <summary>The helper</summary>
    private readonly IActorPathAndFactory helper;

    /// <summary>The log</summary>
    private readonly ILoggingAdapter log = Context.GetLogger();

    /// <summary>The vote execution profile</summary>
    private List<SomethingProcessingObject> voteExecutionProfile = new List<SomethingProcessingObject>();

    /// <summary>
    /// Initializes a new instance of the <see cref="SomethingProcessorActor"/> class.
    /// </summary>
    /// <param name="helper">
    /// The helper.
    /// </param>
    public SomethingProcessorActor(IActorPathAndFactory helper)
    {
        this.helper = helper;
        this.Receive<ProcessSomethings>(
            x =>
                {
                    this.log.Debug("Received: ProcessSomethings");
                    this.BecomeStacked(this.Working);
                    this.RetriveSomethingAndPushForProcessing();
                });
    }



    /// <summary>Supervisors strategy.</summary>
    /// <returns>Supervisors strategy for that actor</returns>
    protected override SupervisorStrategy SupervisorStrategy()
    {
        return new AllForOneStrategy(10, 3000, Decider.From(x => Directive.Stop));
    }



    /// <summary>
    /// The merge data.
    /// </summary>
    private void RetriveSomethingAndPushForProcessing()
    {
     this.log.Debug($"Processing Somethings...");
        var SomethingActor1 = this.helper.GetActorPath(ActorsEnum.SomethingsDataActor);
        var SomethingActor2 =  this.helper.GetActorPath(ActorsEnum.SomethingCollectorActor);
        var something = (SomethingDto)SomethingActor1.Ask(new SomethingsDataActor.GetOneSomethingAndRemoveFromList()).Result;

        while (Something.SomethingId>0)
        {
            this.log.Debug($"Sending data to SomethingCollector with Something id: {Something.SomethingId}");
            SomethingActor2.Tell(new SomethingCollectorActor.ProcessSomethingDto(Something));
            Something = (SomethingDto)SomethingActor1.Ask(new SomethingsDataActor.GetOneSomethingAndRemoveFromList()).Result;
        }

        this.log.Debug("Sending data to SomethingCollector -- ALL SENT");
        this.UnbecomeStacked();
    }

The mock objects just send probe actor as per every request

    public ActorSelection GetActorPath(ActorsEnum actorsEnum)
            {
                Debug.WriteLine("GetDataActorPath for:" + actorsEnum);
                Debug.WriteLine("GetDataActorPath =>" + this.probeRef.Path);

                return this.Sys.ActorSelection(this.probeRef.Path);
            }

            public void SetProbe(IActorRef actorRef)
            {
                Debug.WriteLine("Setting probe reference: " + actorRef.Path);
                this.probeRef = actorRef;
            }

ignition overview

2 个答案:

答案 0 :(得分:1)

好的一些事情。

首先:您期待的是类型为SomethingsDataActor.GetOneSomethingAndRemoveFromList的消息。 但是看起来你实际上并没有将此消息传递给testprobe所代表的actorref。但很难确定,因为你只粘贴了一半的代码。

第二

  • 在演员中使用ask被认为是一种反模式,可以通过采用更具会话风格的沟通方式轻松避免。
  • 使用actor.ask()。结果更糟糕,因为如果你不小心它会导致死锁。 (当数据库actor崩溃时会发生什么情况,因为你的网络已关闭?可能永远不会发回任何响应,默认的Ask timeout是无限的)

Ask应该只用于与演员系统外部的演员进行交流。

答案 1 :(得分:0)

问题在于继承TestClass的模拟类,

决定拥有“演员系统参考”

 return this.Sys.ActorSelection(this.probeRef.Ref.Path);

但应该是:

return this.probeRef.ActorSelection(this.probeRef.Ref.Path);

这种继承创造了第二个独立的演员系统.....

感谢@Dantar的帮助!