Skip to content

Commit 1fac2c7

Browse files
authored
Release/1.1.0 (#15)
* Move `DiagnosticRegistry` to `TestsHelper.SourceGenerator.Diagnostics` namespace * Remove Attribute Requirements to parent class * Remove obsolete `ClassPartialImplementation` * Remove Unused Constructor * Add README to misc folder * Update README * Remove Comment From Test * Feature/setup method for mocks (#13) * Store `ITypeSymbol` and rename `Name` to `ParameterName` * Add Syntax Extensions Methods * Use Syntax Extension methods * Implement Setup Method Generation * Change Samples And Test Sources To Use The Setup Method Generation * Implement void support * Moved models into `Models` Namespace * Create WorkingClassInfo * Move setting SelectedConstructor in SetClass * Extracted Logics Outside `SyntaxTreeMockedFilledPartialClassCreator` * Make `AttributeHelpers` to work with attribute full string string along type * Move Cyber Logics Into A Project And Created An Attribute For GenerateMockWrappers * Mark ClassToFillMockIn is it needs have GenerateMockWrappers attribute * Remove String Cyber Code, Change Implementation to be optional * fix test after generate mocks wrapper is optional, add test to cover this * Use GenerateMockWrappers In Sample.Tests * Update README * Use Syntax Extension In `MockGenerator` * Extracted `SetupMethodResult` to another file * use named argument * remove pipeline on pull_request * add build badge to README * Rename `WrapMockMethodResult` * Rename `WrappingMockMethodCreator` * Implemented Verify Creation, add to tests and add it Sample.Tests * Update README about verify * fix typo in README.md * Incremented Versions
1 parent 1fdba4e commit 1fac2c7

36 files changed

Lines changed: 761 additions & 334 deletions

.github/workflows/CI.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
on:
44
workflow_call:
55
push:
6-
pull_request:
76

87
jobs:
98
build:

README.md

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Mock Filler
2+
[![Build](https://github.com/YarinOmesi/MockFiller/actions/workflows/CI.yml/badge.svg)](https://github.com/YarinOmesi/MockFiller/actions/workflows/CI.yml)
23

34
Creating tested class instance with mocks!
45

56
refer to [Test File Example](./Sample.Tests/Test.cs) to see an example
7+
and [Source Generator Tests](./TestsHelper.SourceGenerator.Tests/MockFillerSourceGeneratorTests.cs).
68

79
## How To Use
810

9-
All you need to do is to mark you test fixture class as `partial`.
11+
All you need to do is to mark your test fixture class as `partial`.
1012

1113
Create field of the desired tested class and mark it with attribute `[FillMocks]`.
1214

@@ -32,6 +34,45 @@ defaultValue[Constructor Parameter Name]
3234
private ILoggerFactory _defaultValueFactory = NullLoggerFactory.Instance;
3335
```
3436

37+
#### Generate Mock Wrappers
38+
39+
By marking the test fixture cass with `[TestsHelper.SourceGenerator.MockWrapping.GenerateMockWrappers]` attribute,
40+
it will generate mock wrappers.
41+
42+
A Setup and verify methods will be generated for each public method of dependencies.
43+
44+
Setup method name template `Setup_<ParameterName>_<MethodName>()`
45+
Verify method name template `Verify_<ParameterName>_<MethodName>()`
46+
47+
##### Demonstration
48+
49+
instead of doing this
50+
51+
```csharp
52+
// Setup
53+
_dependencyMock.Setup(dependency => dependency.MakeString(It.IsAny<int>(), "Yarin"))
54+
.Returns<int>((number) => number.ToString());
55+
56+
// Verify
57+
_dependencyMock.Verify(dependency => dependency.MakeString(It.IsAny<int>(), "Yarin"), Times.Once)
58+
```
59+
60+
you can do this
61+
62+
```csharp
63+
/* -- Setup -- */
64+
// Default parameter is Any
65+
Setup_dependency_MakeString(name:"Yarin")
66+
.Returns<int>(n=> n.ToString());
67+
68+
// Any Not Implicitly assumed
69+
Setup_dependency_MakeString(Value<int>.Any,"Yarin")
70+
.Returns<int>(n=> n.ToString());
71+
72+
/* -- Verify -- */
73+
Setup_dependency_MakeString(Value<int>.Any,"Yarin", Times.Once())
74+
```
75+
3576
### Example
3677

3778
For This Code
@@ -40,34 +81,38 @@ For This Code
4081
// Class Being Tested
4182
public class TestedClass
4283
{
84+
private IDependency _dependency;
4385
private ILogger _logger;
44-
45-
public TestedClass(ILoggerFactory factory)
86+
87+
public TestedClass(IDependency dependency, ILoggerFactory factory)
4688
{
47-
/* Some Code */
89+
/* Code */
4890
}
4991
}
5092

5193
// Test Fixture class
52-
public partial class MyTestFixture
94+
public partial class Test
5395
{
5496
[FillMocks]
55-
private TestedClass _testedClasss;
56-
57-
/* Rest Of The Class */
97+
private TestedClass _testedClass;
98+
99+
/* Rest Of Implementation... */
58100
}
59101
```
60102

61103
The Generated Code Will Be
62104

63105
```csharp
64-
public partial class MyTestFixture
106+
public partial class Test
65107
{
66-
private Mock<ILoggerFactory> _loggerFactoryMock;
108+
private Mock<IDependency> _dependencyMock;
109+
private Mock<ILoggerFactory> _factoryMock;
67110

68-
private TestedClass Build()
69-
{
70-
return new TestedClass(_loggerFactoryMock.Object);
71-
}
111+
private TestedClass Build()
112+
{
113+
_dependencyMock = new Mock<IDependency>();
114+
_factoryMock = new Mock<ILoggerFactory>();
115+
return new TestedClass(_dependencyMock.Object, _factoryMock.Object);
116+
}
72117
}
73-
```
118+
```

Sample.Tests/IDependency.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22

33
public interface IDependency
44
{
5+
public string MakeString(int number);
56

7+
public void Add(string name);
68
}

Sample.Tests/Sample.Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717

1818
<ItemGroup>
1919
<ProjectReference Include="..\TestsHelper.SourceGenerator.Attributes\TestsHelper.SourceGenerator.Attributes.csproj" />
20-
<ProjectReference Include="..\TestsHelper.SourceGenerator\TestsHelper.SourceGenerator.csproj" PrivateAssets="all" ReferenceOutputAssembly="true" OutputItemType="Analyzer" />
20+
<ProjectReference Include="..\TestsHelper.SourceGenerator.MockWrapping\TestsHelper.SourceGenerator.MockWrapping.csproj" />
21+
<ProjectReference Include="..\TestsHelper.SourceGenerator\TestsHelper.SourceGenerator.csproj" PrivateAssets="all" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
2122
</ItemGroup>
2223

2324

Sample.Tests/Test.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using Microsoft.Extensions.Logging;
22
using Microsoft.Extensions.Logging.Abstractions;
3+
using Moq;
34
using NUnit.Framework;
45
using TestsHelper.SourceGenerator.Attributes;
6+
using TestsHelper.SourceGenerator.MockWrapping;
57

68
namespace Sample.Tests;
79

10+
[GenerateMockWrappers]
811
[TestFixture]
912
public partial class Test
1013
{
@@ -21,14 +24,38 @@ public void Setup()
2124
}
2225

2326
[Test]
24-
public void METHOD_On_Effect()
27+
public void Setup_WithoutWrapper()
2528
{
2629
// Arrange
27-
30+
int numbrer = 1;
31+
32+
33+
_dependencyMock.Setup(dependency => dependency.MakeString(It.IsAny<int>()))
34+
.Returns<int>((number) => number.ToString());
35+
2836
// Act
29-
_testedClass.VeryComplicatedLogic();
30-
// Assert
37+
string result = _testedClass.VeryComplicatedLogic(numbrer);
3138

39+
// Assert
40+
_dependencyMock.Verify(dependency => dependency.MakeString(2), Times.Once);
41+
Assert.That(result, Is.EqualTo("2"));
3242
}
33-
}
3443

44+
[Test]
45+
public void Setup_WithWrapper()
46+
{
47+
// Arrange
48+
int number = 1;
49+
50+
51+
Setup_dependency_MakeString()
52+
.Returns<int>(n => n.ToString());
53+
54+
// Act
55+
string result = _testedClass.VeryComplicatedLogic(number);
56+
57+
// Assert
58+
Verify_dependency_MakeString(2, Times.Once());
59+
Assert.That(result, Is.EqualTo("2"));
60+
}
61+
}

Sample.Tests/TestedClass.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public TestedClass(IDependency dependency, ILoggerFactory factory)
1313
_logger = factory.CreateLogger<TestedClass>();
1414
}
1515

16-
public int VeryComplicatedLogic()
16+
public string VeryComplicatedLogic(int number)
1717
{
18-
return 0;
18+
return _dependency.MakeString(number + 1);
1919
}
2020
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using Moq;
6+
7+
namespace TestsHelper.SourceGenerator.MockWrapping;
8+
9+
public static class Cyber
10+
{
11+
// This Method Should Not Be Ran It Used As A Filler For Types
12+
public static T Fill<T>() => throw new NotImplementedException();
13+
14+
public static Expression<T> UpdateExpressionWithParameters<T>(Expression<T> expression, IEnumerable<Expression> arguments)
15+
{
16+
MethodCallExpression body = (MethodCallExpression) expression.Body;
17+
return expression.Update(body.Update(body.Object, arguments), expression.Parameters);
18+
}
19+
20+
public static Expression CreateExpressionFor<T>(Value<T> value)
21+
{
22+
Expression<Func<T>> isAny = () => It.IsAny<T>();
23+
Expression<Func<T>> itIs = () => It.Is<T>(Fill<T>(), EqualityComparer<T>.Default);
24+
MethodCallExpression body = (MethodCallExpression) itIs.Body;
25+
26+
if (value.IsAny)
27+
{
28+
return isAny.Body;
29+
}
30+
31+
List<Expression> newArguments = body.Arguments.ToList();
32+
newArguments[0] = Expression.Constant(value.IsDefault ? default : value._Value);
33+
34+
return body.Update(body.Object, newArguments);
35+
}
36+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace TestsHelper.SourceGenerator.MockWrapping;
4+
5+
[AttributeUsage(AttributeTargets.Class)]
6+
public class GenerateMockWrappersAttribute : Attribute
7+
{
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>10</LangVersion>
6+
</PropertyGroup>
7+
8+
<PropertyGroup>
9+
<Version>1.0.0</Version>
10+
</PropertyGroup>
11+
<ItemGroup>
12+
<PackageReference Include="Moq" Version="4.18.4" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace TestsHelper.SourceGenerator.MockWrapping;
2+
3+
public readonly struct Value<T>
4+
{
5+
public static readonly Value<T> Any = new(default, isAny: true);
6+
public static readonly Value<T> Default = new(default, isDefault: true);
7+
8+
public T _Value { get; }
9+
public bool IsAny { get; }
10+
public bool IsDefault { get; }
11+
12+
13+
public Value(T value, bool isDefault = false, bool isAny = false)
14+
{
15+
_Value = value;
16+
IsDefault = isDefault;
17+
IsAny = isAny;
18+
}
19+
20+
public static implicit operator Value<T>(T value) => new(value);
21+
}

0 commit comments

Comments
 (0)