Skip to content

Always construct mocks as strict#43844

Merged
sharwell merged 5 commits intodotnet:masterfrom
sharwell:strict-mocks
Jun 12, 2020
Merged

Always construct mocks as strict#43844
sharwell merged 5 commits intodotnet:masterfrom
sharwell:strict-mocks

Conversation

@sharwell
Copy link
Contributor

Banned API analyzer is updated to report construction of loose mocks.

@sharwell sharwell requested review from a team as code owners April 30, 2020 20:34
@@ -0,0 +1,2 @@
M:Moq.Mock`1.#ctor; Pass MockBehavior.Strict explicitly to the constructor for Mock<T>
F:Moq.MockBehavior.Loose; Use MockBehavior.Strict for mocks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the first one, but we don't want people to be opting in, even explicitly?

Copy link
Contributor Author

@sharwell sharwell Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Mocks are challenging for maintainability because they do not show up as implementations of classes and interfaces, so they are prone to unintended deviations from adherence to API post-conditions. Loose mocks are the worst case scenario because they also don't show up as references to the API which changed.

Stubs are preferred to mocks because they are true implementations of the API, but one step at a time...

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm 100% for banning the constructor that doesn't specify the MockBehavior.Strict; my concern was also banning MockBehavior.Loose. @sharwell privately made a separate argument that there wasn't much reason to keep it around since for the most part the PR here was trivial and switching things to strict mocks worked just fine, and that's a much better argument to me than the other argument presented -- I'm a firm believer that all tools have a time and place.

Looking at the actual textual diffs though I'm kinda swaying back: there's two places where the loose mock seems fine, and I wish we'd just keep that.

Comment on lines -228 to +231
New Mock(Of IFindPeekResultsCallback)(MockBehavior.Loose).Object)
callbackMock.Object)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda wish we were keeping the loose mock here -- behavior changes really shouldn't require test changes here I don't think...

Comment on lines +40 to +41
Dim mockSVsServiceProvider = New Mock(Of SVsServiceProvider)(MockBehavior.Strict)
mockSVsServiceProvider.Setup(Function(s) s.GetService(GetType(SVsTextManager))).Returns(Nothing)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wish we also had the loose mock here as well. A random implementation change elsewhere doesn't really feel like it should trigger a requirement to add an explicit "Returns(Nothing)" if the test would have already passed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A random implementation change elsewhere doesn't really feel like it should trigger a requirement to add an explicit "Returns(Nothing)" if the test would have already passed.

This is why we don't use Moq.

@sharwell sharwell merged commit 9f8603f into dotnet:master Jun 12, 2020
@ghost ghost added this to the Next milestone Jun 12, 2020
@sharwell sharwell deleted the strict-mocks branch June 12, 2020 23:13
@dibarbet dibarbet modified the milestones: Next, 16.7.P4 Jun 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants