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

new mock sequence - for discussion #1197

Closed
wants to merge 5 commits into from

Conversation

tonyhallett
Copy link
Contributor

@tonyhallett tonyhallett commented Aug 7, 2021

A mock sequence that is

Loose or strict
It captures invocations on the registered mocks and when strict throws if no corresponding sequence setup.
VerifyNoOtherCalls can be used if Loose.

Sequence setups are performed on the mock and captured.
So protected works with the same syntax.

			var mock = new Mock<IFoo>();
			var mocked = mock.Object;
			var protectedMock = new Mock<Protected>();
			var protectedAsMock = protectedMock.Protected().As<ProtectedLike>();
			var protectedMocked = protectedMock.Object;

			var sequence = new NewMockSequence(true, mock, protectedMock);
			sequence.Setup(() => mock.Setup(m => m.Do(1)).Returns(1));
			sequence.Setup(() => protectedAsMock.Setup(m => m.ProtectedDo(2)).Returns(2));
			Assert.Equal(1, mocked.Do(1));
			Assert.Equal(2, protectedMocked.InvokeProtectedDo(2));
			

When specifying the sequence you can use Times to adjust the expectation. The default is Times.Once()

Can be cyclical

			var mock = new Mock<IFoo>();
			var mocked = mock.Object;
			var protectedMock = new Mock<Protected>();
			var protectedAsMock = protectedMock.Protected().As<ProtectedLike>();
			var protectedMocked = protectedMock.Object;
			var sequence = new NewMockSequence(true, mock, protectedMock) { Cyclical = true };
			sequence.Setup(() => mock.Setup(m => m.Do(1)).Returns(1));
			sequence.Setup(() => protectedAsMock.Setup(m => m.ProtectedDo(2)).Returns(2));
			Assert.Equal(1, mocked.Do(1));
			Assert.Equal(2, protectedMocked.InvokeProtectedDo(2));
			Assert.Equal(1, mocked.Do(1));
			Assert.Equal(2, protectedMocked.InvokeProtectedDo(2));

Although a sequence will throw if invocations do not occur as expected in most instances verification is needed.

For non cyclical - every set up has to pass the expectation - Times.
mockSequence.Verify()

For cyclical you would use the return value of a setup.

			var mock = new Mock<IFoo>();
			var mocked = mock.Object;

			var sequence = new NewMockSequence(true, mock) { Cyclical = true };
			var verifiableSetup1 = sequence.Setup(() => mock.Setup(m => m.Do(1)).Returns(1), Times.AtMost(2));
			var verifiableSetup2 = sequence.Setup(() => mock.Setup(m => m.Do(2)).Returns(2));

			mocked.Do(1);
			verifiableSetup1.Verify(1);
			mocked.Do(1);
			verifiableSetup1.Verify(2);
			mocked.Do(2);
			mocked.Do(1);
			verifiableSetup1.Verify(3);

			var exception = Assert.Throws<SequenceException>(() => verifiableSetup1.Verify(4));
			Assert.Equal("Expected invocation on the mock exactly 4 times, but was 3 times: NewMockSequenceFixture.IFoo m => m.Do(1)", exception.Message);

@stakx Please have a look when you get the opportunity.

@ghost
Copy link

ghost commented Feb 26, 2022

@tonyhallett this is interesting, please take also a look to this use case to see if can be handled by your implementation.
Thanks :)

@stakx
Copy link
Contributor

stakx commented Jan 3, 2023

@tonyhallett, I'm going to close this, at least for now. We first need to make a decision at the conceptual level about the future direction for sequences before reviewing nearly 2,000 lines of draft code. This discussion should happen in an issue, not in a PR.

@stakx stakx closed this Jan 3, 2023
@devlooped devlooped locked and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants