Как проверить 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;
}