Как проверить akka.net постоянных актеров

Я использую [Akka.Net 1.3.1] смесь ReceiveActors и ReceivePersistentActors, и теперь я хочу написать тесты для моей актерской системы.

MyPersistentActor наследуется от ReceivePersistentActor, а MyActor наследуется от ReceiveActor.

Я также установил Akka.TestKit, используя версию 1.3.1 .

Но похоже, что Akka.TestKit может проверить только ReceiveActors. IActorRef myActorRef = this.Sys.ActorOf<MyActor>(); // is fine IActorRef myPersistentActorRef = this.Sys.ActorOf<MyPersistentActor>(); // is a problem

Я также нашел пакет nuget Akka.Persistence.TestKit версии 1.2.3.43-beta . Бета не менялась с трех месяцев и поддерживает только akka 1.2.2 . Это все еще в разработке или это мертвый. Я не могу найти какую-либо информацию об этом.

Как вы проверяете своих настойчивых актеров?

Спасибо за вашу помощь!

Richi

1 ответ

Akka.Persistence.TestKit был переименован в Akka.Persistence.TCK и используется только для тестирования пользовательских журналов событий и реализаций хранилища снимков на совместимость с протоколом Akka.Persistence. Это не приносит никаких утилит для тестирования действующих лиц.

Нет встроенных методов взаимодействия с журналами / хранилищами снимков для целей тестирования, кроме их реализаций, работающих в памяти. При этом вы можете работать с хранилищем журналов и снимков, как и с любым другим актером. Если вы посмотрите на реализации таких характеристик TCK, как JournalSpec, вы можете получить представление о том, как работает этот протокол.

Например, если вы хотите инициализировать журнал с некоторыми событиями до запуска тестового примера, вы можете сделать это следующим образом:

void InitWithEvents(string persistenceId, params object[] events)
{
    var probe = CreateTestProbe();
    var writerGuid = Guid.NewGuid().ToString();
    var writes = new AtomicWrite[events.Length];
    for (int i = 0; i < events.Length; i++)
    {
        var e = events[i];
        writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
    }
    var journal = Persistence.Instance.Apply(Sys).JournalFor(null);
    journal.Tell(new WriteMessages(writes, probe.Ref, 1));

    probe.ExpectMsg<WriteMessagesSuccessful>();
    for (int i = 0; i < events.Length; i++)
        probe.ExpectMsg<WriteMessageSuccess>();
}

PS: Ясно, что в API-интерфейсе TestKit для персистентности отсутствует часть, любые вклады в этой области приветствуются.

Я знаю, что это простой ответ, но я не нашел лучшего ресурса. В моих тестах меня на самом деле интересует только то, сохраняется ли правильное событие (я) после того, как я даю свою команду. Сага может вызвать несколько событий. В большинстве случаев меня интересует только последнее сохраненное событие.

Если кто-то сталкивается с той же проблемой, что и я, я исправил получение последнего сообщения на основе Bartosz initWithEvents.

        private void InitWithEvents(string persistenceId, IList<object> events)
        {
            var probe = CreateTestProbe();
            var writerGuid = Guid.NewGuid().ToString();

            var writes = new AtomicWrite[events.Count];
            for (int i = 0; i < events.Count; i++)
            {
                var e = events[i];
                writes[i] = new AtomicWrite(new Persistent(e, i+1, persistenceId, "", false, ActorRefs.NoSender, writerGuid));
            }
            journal = Persistence.Instance.Apply(Sys).JournalFor(null);
            journal.Tell(new WriteMessages(writes, probe.Ref, 1));

            probe.ExpectMsg<WriteMessagesSuccessful>();
            for (int i = 0; i < events.Count; i++)
                probe.ExpectMsg<WriteMessageSuccess>();
        }

        private object GetLastPersistedMessageFromJournal(string persistenceId)
        {
            var repointable = journal as RepointableActorRef;
            var underlying = repointable.Underlying as ActorCell;

            PropertyInfo prop = typeof(ActorCell).GetProperty("Actor", BindingFlags.NonPublic | BindingFlags.Instance);
            MethodInfo getter = prop.GetGetMethod(nonPublic: true);
            MemoryJournal jrnl = getter.Invoke(underlying, null) as MemoryJournal;

            var read = jrnl?.Read(persistenceId, 0, Int64.MaxValue, Int64.MaxValue);
            return read?.Last().Payload;
        }
Другие вопросы по тегам