Skip to content

Commit 2e422ab

Browse files
Merge pull request #1 from PosInformatique/releases/v1.0.0
Initial version with following rules: - MQ1000: `Verify()` and `VerifyAll()` methods should be called when instantiate a `Mock<T>` instances - MQ1001: The `Mock<T> instance behavior should be defined to Strict mode.
2 parents a62f9a7 + 65e50a5 commit 2e422ab

23 files changed

Lines changed: 1723 additions & 1 deletion

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[*.cs]
2+
3+
# StyleCop
4+
5+
# SA1600: Elements should be documented
6+
dotnet_diagnostic.SA1600.severity = none
7+
8+
# SA1601: Partial elements should be documented
9+
dotnet_diagnostic.SA1601.severity = none
10+
11+
# SA1602: Enumeration items should be documented
12+
dotnet_diagnostic.SA1602.severity = none

CodeCoverage.runsettings

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- File name extension must be .runsettings -->
3+
<RunSettings>
4+
<DataCollectionRunSettings>
5+
<DataCollectors>
6+
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
7+
<Configuration>
8+
<CodeCoverage>
9+
10+
<!-- Match assembly file paths: -->
11+
<ModulePaths>
12+
<Include>
13+
<ModulePath>.*\.dll$</ModulePath>
14+
</Include>
15+
<Exclude>
16+
<ModulePath>.*xunit.*</ModulePath>
17+
<ModulePath>.*webjobs.*</ModulePath>
18+
<ModulePath>moq.*</ModulePath>
19+
<ModulePath>.*durabletask.*</ModulePath>
20+
<ModulePath>microsoft.*</ModulePath>
21+
<ModulePath>bouncycastle.*</ModulePath>
22+
<ModulePath>.*tests\.dll$</ModulePath>
23+
</Exclude>
24+
</ModulePaths>
25+
26+
<Attributes>
27+
<Exclude>
28+
<!-- Exclude generated code from code coverage -->
29+
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
30+
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
31+
</Exclude>
32+
</Attributes>
33+
34+
<CompanyNames>
35+
<Include>
36+
<CompanyName>.*PosInformatique.*</CompanyName>
37+
</Include>
38+
</CompanyNames>
39+
40+
<!-- We recommend you do not change the following values: -->
41+
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
42+
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
43+
<CollectFromChildProcesses>True</CollectFromChildProcesses>
44+
<CollectAspDotNet>False</CollectAspDotNet>
45+
46+
</CodeCoverage>
47+
</Configuration>
48+
</DataCollector>
49+
</DataCollectors>
50+
</DataCollectionRunSettings>
51+
</RunSettings>

Directory.Build.props

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<Project>
2+
3+
<!-- Common properties -->
4+
<PropertyGroup>
5+
<Authors>Gilles TOURREAU</Authors>
6+
<Company>P.O.S Informatique</Company>
7+
<Product>P.O.S Informatique</Product>
8+
<Copyright>Copyright (c) P.O.S Informatique. All rights reserved.</Copyright>
9+
<RepositoryUrl>https://github.com/PosInformatique/PosInformatique.Moq.Analyzers</RepositoryUrl>
10+
<RepositoryType>git</RepositoryType>
11+
12+
<!-- Enable the last version of C# -->
13+
<LangVersion>latest</LangVersion>
14+
15+
<!-- Enable implict usings -->
16+
<ImplicitUsings>enable</ImplicitUsings>
17+
18+
<!-- Disable the Analyzers in Release configuration -->
19+
<RunAnalyzers Condition="'$(Configuration)' == 'Release'">false</RunAnalyzers>
20+
21+
<!-- Disable the StyleCop 'XML comment analysis is disabled due to project configuration' warning. -->
22+
<NoWarn>$(NoWarn);SA0001</NoWarn>
23+
24+
<!-- By default prefix all the assemblies name with ChantierConnect -->
25+
<AssemblyName>PosInformatique.$(MSBuildProjectName)</AssemblyName>
26+
<RootNamespace>PosInformatique.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
27+
</PropertyGroup>
28+
29+
<ItemGroup>
30+
<AdditionalFiles Include="..\..\stylecop.json">
31+
<Link>stylecop.json</Link>
32+
</AdditionalFiles>
33+
</ItemGroup>
34+
35+
<!-- Common NuGet packages -->
36+
<ItemGroup>
37+
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
38+
<PrivateAssets>all</PrivateAssets>
39+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
40+
</PackageReference>
41+
</ItemGroup>
42+
43+
<!-- Add the default using directive for all the code -->
44+
<ItemGroup>
45+
<Using Include="System" />
46+
</ItemGroup>
47+
48+
</Project>

PosInformatique.Moq.Analyzers.sln

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.7.34221.43
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.Analyzers.Tests", "tests\Moq.Analyzers.Tests\Moq.Analyzers.Tests.csproj", "{DEE86A7E-8338-4C3D-822B-E8FB976D9905}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.Analyzers", "src\Moq.Analyzers\Moq.Analyzers.csproj", "{1962BEF9-E6DF-4485-A113-E255C84177D4}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1D59B801-B4D3-44FC-A2BE-F2F53AC54061}"
11+
ProjectSection(SolutionItems) = preProject
12+
.editorconfig = .editorconfig
13+
.gitignore = .gitignore
14+
CodeCoverage.runsettings = CodeCoverage.runsettings
15+
Directory.Build.props = Directory.Build.props
16+
LICENSE = LICENSE
17+
README.md = README.md
18+
stylecop.json = stylecop.json
19+
EndProjectSection
20+
EndProject
21+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{4C3E1C72-8977-4ABD-8360-A8707DBBA5AE}"
22+
ProjectSection(SolutionItems) = preProject
23+
build\azure-pipelines-ci.yaml = build\azure-pipelines-ci.yaml
24+
build\azure-pipelines-release.yaml = build\azure-pipelines-release.yaml
25+
EndProjectSection
26+
EndProject
27+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DC2CDF77-88A9-490D-84ED-34832943104A}"
28+
ProjectSection(SolutionItems) = preProject
29+
tests\.editorconfig = tests\.editorconfig
30+
EndProjectSection
31+
EndProject
32+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{3C20D95F-AB5F-44EC-8FB6-CB9827B7FD63}"
33+
EndProject
34+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "design", "design", "{815BE8D0-C7D5-4B4E-82E0-DE29C11F258E}"
35+
ProjectSection(SolutionItems) = preProject
36+
docs\design\MQ1000.md = docs\design\MQ1000.md
37+
docs\design\MQ1001.md = docs\design\MQ1001.md
38+
EndProjectSection
39+
EndProject
40+
Global
41+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
42+
Debug|Any CPU = Debug|Any CPU
43+
Release|Any CPU = Release|Any CPU
44+
EndGlobalSection
45+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
46+
{DEE86A7E-8338-4C3D-822B-E8FB976D9905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{DEE86A7E-8338-4C3D-822B-E8FB976D9905}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{DEE86A7E-8338-4C3D-822B-E8FB976D9905}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{DEE86A7E-8338-4C3D-822B-E8FB976D9905}.Release|Any CPU.Build.0 = Release|Any CPU
50+
{1962BEF9-E6DF-4485-A113-E255C84177D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51+
{1962BEF9-E6DF-4485-A113-E255C84177D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
52+
{1962BEF9-E6DF-4485-A113-E255C84177D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
53+
{1962BEF9-E6DF-4485-A113-E255C84177D4}.Release|Any CPU.Build.0 = Release|Any CPU
54+
EndGlobalSection
55+
GlobalSection(SolutionProperties) = preSolution
56+
HideSolutionNode = FALSE
57+
EndGlobalSection
58+
GlobalSection(NestedProjects) = preSolution
59+
{4C3E1C72-8977-4ABD-8360-A8707DBBA5AE} = {1D59B801-B4D3-44FC-A2BE-F2F53AC54061}
60+
{DC2CDF77-88A9-490D-84ED-34832943104A} = {1D59B801-B4D3-44FC-A2BE-F2F53AC54061}
61+
{3C20D95F-AB5F-44EC-8FB6-CB9827B7FD63} = {1D59B801-B4D3-44FC-A2BE-F2F53AC54061}
62+
{815BE8D0-C7D5-4B4E-82E0-DE29C11F258E} = {3C20D95F-AB5F-44EC-8FB6-CB9827B7FD63}
63+
EndGlobalSection
64+
GlobalSection(ExtensibilityGlobals) = postSolution
65+
SolutionGuid = {3307E7F7-9CD7-4C12-B34A-943F5A8B62A4}
66+
EndGlobalSection
67+
EndGlobal

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,30 @@
11
# PosInformatique.Moq.Analyzers
2-
PosInformatique.Moq.Analyzers is a library to verify syntax and code design when writing the unit tests using the Moq library.
2+
PosInformatique.Moq.Analyzers is a library to verify syntax and code design when writing the unit tests using the [Moq](https://github.com/devlooped/moq) library.
3+
4+
## Installing from NuGet
5+
The [PosInformatique.Moq.Analyzers](https://www.nuget.org/packages/PosInformatique.FluentAssertions.Json/)
6+
library is available directly on the
7+
[![Nuget](https://img.shields.io/nuget/v/PosInformatique.Moq.Analyzers)](https://www.nuget.org/packages/PosInformatique.Moq.Analyzers/)
8+
official website.
9+
10+
To download and install the library to your Visual Studio unit test projects use the following NuGet command line
11+
12+
```
13+
Install-Package PosInformatique.Moq.Analyzers
14+
```
15+
16+
The analyzer is automatically added and activated with their default severity levels.
17+
18+
## Rules
19+
20+
This section describes the list of the rules analyzed by the library to improve code quality of the unit tests using
21+
the [Moq](https://github.com/devlooped/moq) library.
22+
23+
### Design
24+
25+
Design rules used to make your unit tests more strongly strict.
26+
27+
| Rule | Description |
28+
| - | - |
29+
| [MQ1000: `Verify()` and `VerifyAll()` methods should be called when instantiate a `Mock<T>` instances](docs/design/MQ1000.md) | When instantiating a `Mock<T>` in the *Arrange* phase of an unit test, `Verify()` or `VerifyAll()` method should be called in the *Assert* phase to check the setup methods has been called. |
30+
| [MQ1001: The `Mock<T>` instance behavior should be defined to Strict mode](docs/design/MQ1001.md) | When instantiating a `Mock<T>` instance, the `MockBehavior` of the `Mock` instance should be defined to `Strict`. |

build/azure-pipelines-ci.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
trigger: none
2+
3+
pool:
4+
vmImage: ubuntu-latest
5+
6+
jobs:
7+
- job: Build
8+
displayName: Build the library
9+
steps:
10+
- task: DotNetCoreCLI@2
11+
name: BuildLibrary
12+
displayName: Build the library
13+
inputs:
14+
command: 'build'
15+
projects: 'PosInformatique.Moq.Analyzers.sln'
16+
arguments: '--property:Configuration=Debug'
17+
18+
- task: DotNetCoreCLI@2
19+
name: ExecuteUnitTests
20+
displayName: Execute the unit tests
21+
inputs:
22+
command: 'test'
23+
projects: 'PosInformatique.Moq.Analyzers.sln'
24+
arguments: '--property:Configuration=Debug'

build/azure-pipelines-release.yaml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
parameters:
2+
- name: VersionPrefix
3+
displayName: The version of the library
4+
type: string
5+
default: 1.0.0
6+
- name: VersionSuffix
7+
displayName: The version suffix of the library (rc.1). Use a space ' ' if no suffix.
8+
type: string
9+
default: rc.1
10+
11+
trigger: none
12+
pr: none
13+
14+
pool:
15+
vmImage: ubuntu-latest
16+
17+
jobs:
18+
- job: Build
19+
displayName: Build the library
20+
steps:
21+
- task: PowerShell@2
22+
name: UpdateBuildNumber
23+
displayName: Update build number
24+
inputs:
25+
targetType: 'inline'
26+
script: '
27+
if ("${{parameters.VersionSuffix}}".Trim() -eq "")
28+
{
29+
Write-Host "##vso[build.updatebuildnumber]${{parameters.VersionPrefix}}"
30+
}
31+
else
32+
{
33+
Write-Host "##vso[build.updatebuildnumber]${{parameters.VersionPrefix}}-${{parameters.VersionSuffix}}"
34+
}'
35+
36+
- task: DotNetCoreCLI@2
37+
name: BuildLibrary
38+
displayName: Build the library
39+
inputs:
40+
command: 'pack'
41+
packagesToPack: 'src/Moq.Analyzers/Moq.Analyzers.csproj'
42+
configuration: 'Release'
43+
versioningScheme: 'off'
44+
buildProperties: 'VersionPrefix=${{parameters.VersionPrefix}};VersionSuffix=${{parameters.VersionSuffix}}'
45+
verbosityPack: 'Normal'
46+
47+
- task: NuGetCommand@2
48+
name: PublishNuGetPackages
49+
displayName: Publish to NuGet
50+
inputs:
51+
command: 'push'
52+
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
53+
nuGetFeedType: 'external'
54+
publishFeedCredentials: 'nuget.org'

docs/design/MQ1000.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# MQ1000: `Verify()` and `VerifyAll()` methods should be called when instantiate a `Mock<T>` instances
2+
3+
| Property | Value |
4+
|-------------------------------------|--------------------------------------------------------------------------------------------|
5+
| **Rule ID** | MQ1000 |
6+
| **Title** | `Verify()` and `VerifyAll()` methods should be called when instantiate a Mock<T> instances |
7+
| **Category** | Design |
8+
| **Default severity** | Warning |
9+
10+
## Cause
11+
12+
A `Verify()` or `VerifyAll()` of an `Mock<T>` instance has not been called in the *Assert* phase
13+
of an unit test.
14+
15+
## Rule description
16+
17+
When instantiating a `Mock<T>` in the *Arrange* phase of an unit test, `Verify()` or `VerifyAll()` method
18+
should be called in the *Assert* phase to check the setup methods has been called.
19+
20+
```csharp
21+
[Fact]
22+
public void GetCustomer_ShouldCallRepository()
23+
{
24+
// Arrange
25+
var smtpService = new Mock<ISmtpService>();
26+
smtpService.Setup(s => s.SendMail("sender@domain.com", "Gilles"));
27+
28+
var service = new CustomerService(repository.Object);
29+
30+
// Act
31+
service.SendMail("Gilles");
32+
33+
// Arrange
34+
smtpService.VerifyAll(); // The VerifyAll() will check that the mocked ISmtpService.SendMail() has been called.
35+
}
36+
```
37+
38+
## How to fix violations
39+
40+
To fix a violation of this rule, call the `Verify()` or `VerifyAll()` in the *Assert* phase
41+
on the `Mock<T>` instances created during the *Arrange* phase.
42+
43+
## When to suppress warnings
44+
45+
Do not suppress a warning from this rule. Normally all setup methods must be called.

0 commit comments

Comments
 (0)