我有一个演员,要求其他演员和未来可以回退到其他人:
class Subject(db: ActorRef) extends Actor with ActorLogging {
implicit val timeout = Timeout(1 seconds)
implicit val ec = context.system.dispatcher
override def preStart(): Unit = {
db ? "auth" fallbackTo Future {
"auth:timeout_error"
} pipeTo self
}
def receive: Receive = {
case msg: String => log.info(msg)
}
}
我需要测试回退行为,但不知道该怎么做:
class ActorSpec extends TestKit(ActorSystem("MySpec"))
with ImplicitSender with WordSpecLike with BeforeAndAfterAll with BeforeAndAfterEach with Matchers {
val db = TestProbe()
db.ref ! PoisonPill
//db not exist anymore
val subject = system.actorOf(Props(new Subject(db.ref)))
//Something like: subject should receive "auth:timeout_error"
}
如何正确执行此任务?
答案 0 :(得分:1)
您可以覆盖接收方法并向TestProbe()
发送消息import java.sql.*;
public class JDBCDemo {
public static void main(String[] args) {
String url="jdbc:oracle:thin:@//localhost:1521/xe";
String un="system";
String pwd="system";
Connection con=null;
Statement stmt=null;
ResultSet res=null;
try{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
System.out.println("Driver Loaded successfully");
}
catch(Exception e)
{
System.out.println("Driver not loaded");
}
try{
DriverManager.getConnection(url,un,pwd);
System.out.println("Connection established");
}
catch(Exception f)
{
System.out.println("Connection not established");
}
try{
String s="Select * from student";
stmt=con.createStatement();
res=stmt.executeQuery(s);
System.out.println("Query executed succesfully");
}
catch(Exception e)
{
System.out.println("Query not executed");
}
答案 1 :(得分:1)
执行测试的最简单方法是重构Subject
类,为db
参数添加抽象级别。 Subject
中没有任何东西本质上取决于db是ActorRef
的事实; Subject
只需要一些内容即可向String
发送查询并收到Future[String]
响应。因此,您可以通过接受函数使构造函数更通用:
object Subject {
type Query = String
type DBResult = Future[String]
type DB : (Query) => DBResult
val defaultAuth : DBResult = Future.successful("auth:timeout_error")
val authQuery : Query = "auth"
def queryWithDefault(db : DB, default : DBResult = defaultAuth) : DB =
(query : Query) => db(query) fallbackTo default
}//end object Subject
class Subject(db : Subject.DB) extends Actor with ActorLogging {
override def preStart() : Unit = {
db(Subject.authQuery) pipeTo self
}
override def receive : Receive = {
case msg : String => log info msg
}
}//end class Subject
您现在可以测试queryWithDefault
功能而无需使用akka:
import org.scalatest.{Matchers, WordSpecLike}
import org.scalatest.concurrent.ScalaFutures
class SubjectSpec
extends Matchers
with WorkSpecLike
with ScalaFutures {
val alwaysFail : DB =
(query : Query) => Future.failed(new Exception("always fails"))
import Subject.{defaultAuth, queryWithDefault, authQuery}
"queryWithDefault" should {
"always return default when db fails" in {
val db = queryWithDefault(alwaysFail, defaultAuth)
whenReady(
for {
authQueryRes <- db(authQuery)
fooQueryRes <- db("foo")
defaultRes <- defaultAuth
}) {
authQueryRes shouldEqual defaultRes
fooQueryRes shouldEqual defaultRes
}
}//end "always return..."
}//end "queryWithDefault" should
}//end class SubjectSpec
然后,您可以在生产中使用重构的和单元测试的Subject.queryWithDefault
函数:
val actorDB : DB = (query : Query) => (db.ref ? query).mapTo[String]
val subject = system.actorOf(Props(queryWithDefault(actorDB, defaultAuth)))