Akka Notes –演员记录和测试
在前兩部分( 一 , 二 )中,我們簡要討論了Actor以及消息傳遞的工作方式。 在這一部分中,讓我們看一下如何修復并記錄我們的TeacherActor 。
概括
這就是我們上一部分中的Actor的樣子:
使用SLF4J記錄Akka
您會注意到,在代碼中,我們正在將quoteResponse打印到標準輸出,您顯然會認為這是一個壞主意。 讓我們通過啟用SLF4J Facade日志進行修復。
1.修復類以使用日志記錄
Akka提供了一個很好的小特征ActorLogging來實現它。 讓我們混合:
class TeacherLogActor extends Actor with ActorLogging {val quotes = List("Moderation is for cowards","Anything worth doing is worth overdoing","The trouble is you think you have time","You never gonna know if you never even try")def receive = {case QuoteRequest => {import util.Random//get a random element (for now)val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size)))log.info(quoteResponse.toString())}}//We'll cover the purpose of this method in the Testing sectiondef quoteList=quotes}繞道走一圈:
在內部,當我們記錄一條消息時,ActorLogging中的記錄方法(最終)將日志消息發布到EventStream 。 是的,我確實說過publish 。 那么,EventStream實際上是什么?
EventStream和記錄
EventStream行為就像我們可以向其發布和接收消息的消息代理一樣。 與常規MOM的一個細微區別是EventStream的訂閱者只能是Actor。
在記錄消息的情況下,所有日志消息都將發布到EventStream。 默認情況下,訂閱這些消息的Actor是DefaultLogger ,它僅將消息打印到標準輸出中。
class DefaultLogger extends Actor with StdOutLogger { override def receive: Receive = {...case event: LogEvent ? print(event)} }因此,這就是我們嘗試啟動StudentSimulatorApp的原因,我們看到了寫入控制臺的日志消息。
也就是說,Eve??ntStream不僅適合于記錄。 它是VM內ActorWorld內部可用的通用發布-訂閱機制(稍后會詳細介紹)。
返回SLF4J設置:
2.將Akka配置為使用SLF4J
akka{ loggers = ["akka.event.slf4j.Slf4jLogger"]loglevel = "DEBUG"logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" }我們將此信息存儲在一個名為application.conf的文件中,該文件應該在您的類路徑中。 在我們的sbt文件夾結構中,我們會將其放在您的main/resources目錄中。
從配置中,我們可以得出:
但是,為什么前面的示例沒有提供application.conf?
僅僅是因為Akka提供了一些合理的默認值,所以我們在開始使用它之前不需要構建配置文件。 為了自定義各種內容,我們將在這里經常重新訪問該文件。 您可以在application.conf內部使用一堆很棒的參數來單獨記錄日志。 它們在這里詳細解釋。
3.放入logback.xml
現在,我們將配置一個由logback支持的SLF4J記錄器。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="FILE"class="ch.qos.logback.core.rolling.RollingFileAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>logs\akka.%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><root level="DEBUG"><appender-ref ref="FILE" /></root> </configuration>我也將它與application.conf一起放入了main/resources文件夾中。 請確保main/resources現在位于Eclipse或其他IDE的類路徑中。 還應將logback和slf4j-api包含到build.sbt中 。
而當我們揭開序幕我們StudentSimulatorApp和發送郵件到我們的新TeacherLogActor ,該akkaxxxxx.log文件,我們配置看起來像這樣。
測試Akka
請注意,這絕不是Test Akka的詳盡介紹。 我們將在以下各部分中相應標題下的“測試”的更多功能上構建測試。 這些測試用例旨在覆蓋我們之前編寫的Actor。
當StudentSimulatorApp我們的需求時,您將同意應將其從測試用例中刪除。
為了減輕測試的痛苦,Akka提出了一個了不起的測試工具包,使用它我們可以做一些神奇的事情,例如直接探查Actor實現的內部。
聊夠了,讓我們看看測試用例。
首先讓我們嘗試將StudentSimulatorApp映射到測試用例。
現在讓我們單獨看一下聲明。
class TeacherPreTest extends TestKit(ActorSystem("UniversityMessageSystem")) with WordSpecLikewith MustMatcherswith BeforeAndAfterAll {因此,從TestCase類的定義中,我們看到:
1、2 –向演員發送消息
3 –維護參與者的內部狀態
第三種情況使用TestActorRef的underlyingActor quoteList方法,并調用TeacherActor的quoteList方法。 quoteList方法返回引號列表。 我們使用此列表來聲明其大小。
如果對quoteList引用使您退縮,請參考上面列出的TeacherLogActor代碼,并查找:
//From TeacherLogActor //We'll cover the purpose of this method in the Testing sectiondef quoteList=quotes//3. Asserts the internal State of the Log Actor. "have a quote list of size 4" in {val teacherRef = TestActorRef[TeacherLogActor]teacherRef.underlyingActor.quoteList must have size (4)teacherRef.underlyingActor.quoteList must have size (4)}4 –聲明日志消息
正如我們前面在EventStream和Logging部分(上文)中所討論的,所有日志消息都發送到EventStream ,并且SLF4JLogger訂閱并使用其附加程序將其寫入日志文件/控制臺等。直接在我們的測試用例中使用EventStream并斷言日志消息本身的存在? 看起來我們也可以做到。
這涉及兩個步驟:
EventFilter.info塊僅攔截1條以QuoteResponse( pattern='QuoteResponse* )開頭的日志消息。 (您也可以通過使用start='QuoteResponse' 。如果沒有消息發送給TeacherLogActor,則該測試用例將失敗。
5 –使用構造函數參數測試Actor
請注意,我們在測試用例中創建Actor的方式是通過TestActorRef[TeacherLogActor]而不是通過system.actorOf 。 這只是為了使我們可以通過TeacherActorRef中的underlyingActor Actor方法訪問Actor的內部。 我們將無法通過在常規運行時可以訪問的ActorRef來實現此ActorRef 。 (這并沒有給我們在生產中使用TestActorRef的任何借口。您會被追捕的)。
如果Actor接受參數,那么我們創建TestActorRef的方式將是:
val teacherRef = TestActorRef(new TeacherLogParameterActor(quotes))整個測試用例將如下所示:
//5. have a quote list of the same size as the input parameter" have a quote list of the same size as the input parameter" in {val quotes = List("Moderation is for cowards","Anything worth doing is worth overdoing","The trouble is you think you have time","You never gonna know if you never even try")val teacherRef = TestActorRef(new TeacherLogParameterActor(quotes))//val teacherRef = TestActorRef(Props(new TeacherLogParameterActor(quotes)))teacherRef.underlyingActor.quoteList must have size (4)EventFilter.info(pattern = "QuoteResponse*", occurrences = 1) intercept {teacherRef ! QuoteRequest}}關閉ActorSystem
最后, afterAll生命周期方法:
override def afterAll() { super.afterAll()system.shutdown()}碼
- 與往常一樣,可以從github這里下載整個項目。
翻譯自: https://www.javacodegeeks.com/2014/10/akka-notes-actor-logging-and-testing.html
總結
以上是生活随笔為你收集整理的Akka Notes –演员记录和测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 称重收银一体机怎么设置(收银机称重商品设
- 下一篇: 华为路由Q6电力版华为路由器电力线网速如