Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagec#
themeEmacs
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Akka.TestKit" Version="1.3.5" />
    <PackageReference Include="Akka.TestKit.NUnit3" Version="1.3.2" />
    <PackageReference Include="nunit" Version="3.11.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
    <PackageReference Include="Akka" Version="1.3.5" />
  </ItemGroup>

</Project>


여기서 샘플은 Nunit를 선택하였습니다. 


유닛 테스트 작성하기

서비스 코드

Code Block
languagec#
themeEmacs
linenumberstrue
using System;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Event;

namespace AkkaNetCore.Actors
{
    public class CashGateActor : ReceiveActor
    {
        private readonly ILoggingAdapter logger = Context.GetLogger();
        private readonly string id;
        private Random rnd;

        public CashGateActor(int delay)
        {
            rnd = new Random();
            id = Guid.NewGuid().ToString();
            logger.Info($"현금정산게이트 액터 생성:{id} {delay}");

            ReceiveAsync<string>(async msg =>
            {
                //현금정산에 걸리는시간 1~10초, 0일때는 랜덤, 값이 주어질땐 주어진만큼                 
                int auto_delay = delay==0 ? rnd.Next(1000, 10000) : delay;
                await Task.Delay(auto_delay);
                logger.Info($"{msg}-{auto_delay}");
                Sender.Tell($"정산완료 통과하세요");
            });
        }        
    }
}

앞장 성능 확장을 위한 톨게이트 모델에서 현금정산소 Actor를 이용하여 메시지에대한 유닛테스트를 작성해보겠습니다.

메시지를 받으면 지정된 지연시간만큼(for test) 응답을 하는 심플한 코드입니다. -모듈작성때부터 유닛테스트 가능한 방법으로 작성이되면, 유닛테스트 이용과는 별개로 테스트가능한 모듈은 사용성도 높아지게되며 결국 코드품질이 높아지게됩니다.


유닛테스트

테스트 작성

Code Block
languagec#
themeEmacs
linenumberstrue
using System;
using Akka.Actor;
using Akka.TestKit;
using Akka.TestKit.NUnit3;
using AkkaNetCore.Actors;
using NUnit.Framework;

namespace AkkaNetCoreTest.Actors
{
    class ActorBaseTest : TestKit
    {
        TestProbe probe;

        [SetUp]
        public void Setup()
        {
            probe = this.CreateTestProbe();
        }
        
        [TestCase(100, 300)]
        public void Actor_should_respond_within_max_allowable_time(int delay, int cutoff)
        {
            var cashGate = Sys.ActorOf(Props.Create(() => new CashGateActor(delay)));
            // sets a maximum allowable time for entire block to finish
            Within(TimeSpan.FromMilliseconds(cutoff), () =>
            {
                cashGate.Tell("정산게이트 통과요청");
                ExpectMsg("정산완료 통과하세요");
            });
        }
    }
}

테스트 수행

Image Added

이렇게 작성되어진 유닛테스트는 테스트 탐색기를 통해 특정 테스트만 수행할수도 있고 전체를 수행할수도 있습니다.

비동기 처리메시지를 액터와 연동함으로 비동기 메시징에 대한 처리를 유연하게 함과 동시에 심플하고 강력한 방법으로 유닛테스트기를 작성할수가 있습니다.


Note

간혹 카프카를 사용하여 시스템간 메시징 처리시스템이 구현되어야 할경우 Actor사용이 필요 없을수도 있습니다.
하지만 이것은 잘못된 생각입니다.
Kafka와 연동된 커스텀 모듈이 동기처리를 한다거나, 로컬내에서 올바른 분배전략을 세우지 못한다고
유닛테스트가 불가능하다고 하면 Kafka의 끝점연결을 Actor로 하는것을 고려해보십시오
사용해야할 메시징이 늘어남에따라 KafkaTools에서 메시지 검사를 수동으로 하는것이 언젠가 한계가 올것입니다.


참고링크