Akka.net 尽管有 ActorInitializationException 异常,但 Testkit 不会将测试用例标记为失败
Akka.net Testkit does not mark test case failed despite ActorInitializationException exception
以下是演员,我已经定义(试图让我的头脑围绕坚持不懈的演员!!)
public class Country : ReceivePersistentActor
{
public override string PersistenceId => GetType().Name + state.Id;
private CountryState state;
public Country()
{
Command<CreateCountry>(CreateCountry);
}
private bool CreateCountry(CreateCountry cmd)
{
Persist(new CountryCeated
{
Id = cmd.Id,
Code = cmd.Code,
Description = cmd.Description,
Active = cmd.Active
}, evt =>
{
state = new CountryState
{
Id = evt.Id,
Code = evt.Code,
Description = evt.Description,
Active = evt.Active
};
});
return true;
}
}
以下是我定义的单元测试用例:
[TestClass]
public class CountrySpec : TestKit
{
[TestMethod]
public void CountryActor_Should_Create_A_Country()
{
var country = Sys.ActorOf(Props.Create(() => new Country()), "Country");
country.Tell(new CreateCountry(Guid.NewGuid(), "UK", "United Kingdom", true));
ExpectNoMsg();
}
}
当我运行测试用例时,我可以在测试用例window的输出中看到一个异常
[ERROR][25/08/2016 08:25:07][Thread 0007][akka://test/user/Country] Object reference not set to an instance of an object.
Cause: [akka://test/user/Country#552449332]: Akka.Actor.ActorInitializationException: Exception during creation ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Domain.Country.get_PersistenceId() in Y:\Spikes\StatefulActors\Domain\Country.cs:line 9
at Akka.Persistence.Eventsourced.StartRecovery(Recovery recovery)
at Akka.Persistence.Eventsourced.AroundPreStart()
at Akka.Actor.ActorCell.<>c__DisplayClass154_0.<Create>b__0()
at Akka.Actor.ActorCell.UseThreadContext(Action action)
at Akka.Actor.ActorCell.Create(Exception failure)
--- End of inner exception stack trace ---
at Akka.Actor.ActorCell.Create(Exception failure)
at Akka.Actor.ActorCell.SysMsgInvokeAll(EarliestFirstSystemMessageList messages, Int32 currentState)
但是测试用例被标记为成功
TestKit中有没有way/settings,可以设置任何异常,标记测试用例失败?
默认情况下,actors 内部的任何异常都被封装了——这意味着它们不会冒泡,从而破坏系统的其余部分。
演员进入系统,可以通过观察他们相互交流的方式来测试。通常它会提供输入并断言演员系统的输出 - 在您的案例中测试已通过,因为您尚未验证任何输出。从你测试的角度来看,这个演员可能已经死了,这不会有什么不同。
验证输出(通过 actor 本身内部的断言或即使用自定义测试日志)是使用测试的最佳方式。
如果出于某种原因您仍然需要捕获参与者内部的异常,您可以创建绑定到 TestActor
的监督策略,其中可以转发所有异常:
public class TestingStrategy : OneForOneStrategy
{
protected TestingStrategy(IActorRef probe) : base(exception =>
{
probe.Tell(exception);
return DefaultDecider.Decide(exception);
}) { }
}
以下是演员,我已经定义(试图让我的头脑围绕坚持不懈的演员!!)
public class Country : ReceivePersistentActor
{
public override string PersistenceId => GetType().Name + state.Id;
private CountryState state;
public Country()
{
Command<CreateCountry>(CreateCountry);
}
private bool CreateCountry(CreateCountry cmd)
{
Persist(new CountryCeated
{
Id = cmd.Id,
Code = cmd.Code,
Description = cmd.Description,
Active = cmd.Active
}, evt =>
{
state = new CountryState
{
Id = evt.Id,
Code = evt.Code,
Description = evt.Description,
Active = evt.Active
};
});
return true;
}
}
以下是我定义的单元测试用例:
[TestClass]
public class CountrySpec : TestKit
{
[TestMethod]
public void CountryActor_Should_Create_A_Country()
{
var country = Sys.ActorOf(Props.Create(() => new Country()), "Country");
country.Tell(new CreateCountry(Guid.NewGuid(), "UK", "United Kingdom", true));
ExpectNoMsg();
}
}
当我运行测试用例时,我可以在测试用例window的输出中看到一个异常
[ERROR][25/08/2016 08:25:07][Thread 0007][akka://test/user/Country] Object reference not set to an instance of an object.
Cause: [akka://test/user/Country#552449332]: Akka.Actor.ActorInitializationException: Exception during creation ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Domain.Country.get_PersistenceId() in Y:\Spikes\StatefulActors\Domain\Country.cs:line 9
at Akka.Persistence.Eventsourced.StartRecovery(Recovery recovery)
at Akka.Persistence.Eventsourced.AroundPreStart()
at Akka.Actor.ActorCell.<>c__DisplayClass154_0.<Create>b__0()
at Akka.Actor.ActorCell.UseThreadContext(Action action)
at Akka.Actor.ActorCell.Create(Exception failure)
--- End of inner exception stack trace ---
at Akka.Actor.ActorCell.Create(Exception failure)
at Akka.Actor.ActorCell.SysMsgInvokeAll(EarliestFirstSystemMessageList messages, Int32 currentState)
但是测试用例被标记为成功
TestKit中有没有way/settings,可以设置任何异常,标记测试用例失败?
默认情况下,actors 内部的任何异常都被封装了——这意味着它们不会冒泡,从而破坏系统的其余部分。
演员进入系统,可以通过观察他们相互交流的方式来测试。通常它会提供输入并断言演员系统的输出 - 在您的案例中测试已通过,因为您尚未验证任何输出。从你测试的角度来看,这个演员可能已经死了,这不会有什么不同。
验证输出(通过 actor 本身内部的断言或即使用自定义测试日志)是使用测试的最佳方式。
如果出于某种原因您仍然需要捕获参与者内部的异常,您可以创建绑定到 TestActor
的监督策略,其中可以转发所有异常:
public class TestingStrategy : OneForOneStrategy
{
protected TestingStrategy(IActorRef probe) : base(exception =>
{
probe.Tell(exception);
return DefaultDecider.Decide(exception);
}) { }
}