Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation on writing unit tests for Actors that access state #1169

Open
jaq316 opened this issue Oct 17, 2023 · 2 comments
Open

Documentation on writing unit tests for Actors that access state #1169

jaq316 opened this issue Oct 17, 2023 · 2 comments

Comments

@jaq316
Copy link

jaq316 commented Oct 17, 2023

Documentation on writing unit tests, specifically for Actors accessing state would be great.

The below code, for instance, would throw: "InvalidOperationException: The actor was initialized without a state provider, and so cannot interact with state. If this is inside a unit test, replace Actor.StateProvider with a mock."

    internal class MyActor : Actor, IMyActor
    {

        private const string STATE_KEY = "counter";

        public MyActor(ActorHost host) // Accept ActorHost in the constructor
            : base(host) // Pass ActorHost to the base class constructor
        {
        }

        public async Task<int> GetCounter()
        {
            var iCounterState  =(await StateManager.TryGetStateAsync<int>(STATE_KEY).ConfigureAwait(false));
            return iCounterState.Value;
        }
        public async Task Increment()
        {
            var iCounterState = (await StateManager.TryGetStateAsync<int>(STATE_KEY).ConfigureAwait(false));
            if (iCounterState.HasValue)
            {
                await StateManager.SetStateAsync(STATE_KEY, iCounterState.Value + 1).ConfigureAwait(false);
            }
            else
            {
                await StateManager.SetStateAsync(STATE_KEY, 1).ConfigureAwait(false);
            }   
            
        }

    }

    public class MyActorTests
    {
        [Fact]
        public async Task SomeMethod_ShouldSucceed()
        {
            // Arrange
            var actorId = new ActorId("test");
            var host = ActorHost.CreateForTest<MyActor>(new ActorTestOptions
            {
                ActorId = actorId
            });

            var myActor = new MyActor(host);

            // Act
            await myActor.Increment();

            var counter = myActor.GetCounter();
            // Assert
            Assert.AreEqual(1, counter);

        }
    }
@jaq316 jaq316 changed the title Document how to write unit test for Actors Document how to write unit test for Actors that access state Oct 17, 2023
@jaq316 jaq316 changed the title Document how to write unit test for Actors that access state Documentation on writing unit tests for Actors that access state Oct 17, 2023
@jaq316
Copy link
Author

jaq316 commented Oct 18, 2023

https://github.com/dapr/dotnet-sdk/blob/3b979e6bdb1d779563f1656fa684183b2bfecd08/test/Dapr.Actors.Test/ITestActor.cs#L47C31-L47C31 implements overriding of the StateManager by providing an optional IStateManager parameter in the constructor. If that is provided, this.StateManager is set in the constructor.

@paule96
Copy link

paule96 commented Aug 12, 2024

@jaq316 is this a recommendation to provide an IActorStartManager parameter in every actor, so it is testable?
That sounds kinda strange because in the real world the Actors doesn't need this injecten

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants