Skip to content

Commit bd06ec4

Browse files
authored
Release 2.0.0 (#19)
* 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 * Udpdate Dev With Master (#17) * Rename `MockFillerOutput` to `FileResult` * Remove Field Declaration From GeneratedMock.cs * Add Syntax Extensions * Add `TypeMockResult` as the result for class type wrapper * Make `IMockedFilledPartialClassCreator` `Build()` return multiple file result instead of one * Fixed To Use Multiple Files * `BuildMethodCreator` : Use `TypeMockResult` and new syntax extensions * Implement Type Wrapping in `TypeMockWrapperCreator` and deleted the old wrapping method class * Use New Type Mock Wrapping and return multiple files * Update Sample.Tests to use new interface * Update Test To the new interface * Remove unused `WrapMockMethodResult` * Do Not Create Method Wrapper Class When `createMockWrapperMethod` is false and fixed tests * Used `typeMockResult.Namespace` to import wrapper class * Replace `MockProperty` with `MockPropertyName` * Rename `CreateExpressionLambda()` to `CreateMoqExpressionLambda()` * suppress field not initialized * remove unsued field * Rename `_Value` to `ActualValue` and make the ctor private * Removed Unused usings * Format `Test` * Now Using the non incremental generator * Updated README with the new interface * Put Some emojis in README * Split Example Code in README * Change Case of examples links * Add Cyber Testing Project * Add Expression Comparing From GitHub * Refactor `ExpressionComparison` and make it assert instead of boolean * Add Test To `Cyber` clas * Incremented Version To `2.0.0`
1 parent 1fac2c7 commit bd06ec4

32 files changed

Lines changed: 1085 additions & 367 deletions

README.md

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,54 @@
1-
# Mock Filler
1+
# Mock Filler :star:
22
[![Build](https://github.com/YarinOmesi/MockFiller/actions/workflows/CI.yml/badge.svg)](https://github.com/YarinOmesi/MockFiller/actions/workflows/CI.yml)
33

44
Creating tested class instance with mocks!
55

6-
refer to [Test File Example](./Sample.Tests/Test.cs) to see an example
7-
and [Source Generator Tests](./TestsHelper.SourceGenerator.Tests/MockFillerSourceGeneratorTests.cs).
6+
Refer to [Test File Example](./Sample.Tests/Test.cs) to see an example,
7+
Or the tests [Source Generator Tests](./TestsHelper.SourceGenerator.Tests/MockFillerSourceGeneratorTests.cs).
88

99
## How To Use
1010

1111
All you need to do is to mark your test fixture class as `partial`.
1212

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

15-
The Source Generator will fill mocks field and create a `Build()` method to create the instance.
15+
The Source Generator will Create **a field for each mocked parameters with the same name**, and create a `Build()` method to create the instance.
1616

1717
### Features
1818

1919
#### FillMocks
2020

2121
To Fill Mocks for given tested class, create a field for that class and mark it with `[FillMocks]`
22+
```csharp
23+
[FillMocks]
24+
private TestedClass _testedClass;
25+
```
26+
27+
To access a mock of parameter named `loggerFactory`
28+
```csharp
29+
_loggerFactory.Mock // Mock<ILoggerFactory>
30+
```
2231

2332
#### Default Value
2433

2534
To declare a default value instead of creating a mock, create a field with name as following:
2635

2736
defaultValue[Constructor Parameter Name]
2837

29-
> you can add underscore and change the casing
30-
31-
##### Demonstration
38+
> :exclamation: Be aware that default value is case insensitive
3239
40+
To set a default value for parameter named `factory`
3341
```csharp
3442
private ILoggerFactory _defaultValueFactory = NullLoggerFactory.Instance;
3543
```
3644

37-
#### Generate Mock Wrappers
45+
#### Generate Mock Wrappers :crystal_ball:
3846

39-
By marking the test fixture cass with `[TestsHelper.SourceGenerator.MockWrapping.GenerateMockWrappers]` attribute,
40-
it will generate mock wrappers.
47+
Generate Mock Wrappers By marking the class with `[TestsHelper.SourceGenerator.MockWrapping.GenerateMockWrappers]` attribute.
4148

42-
A Setup and verify methods will be generated for each public method of dependencies.
49+
The mocked parameter **field will have a property for each public method** in the mocked type.
4350

44-
Setup method name template `Setup_<ParameterName>_<MethodName>()`
45-
Verify method name template `Verify_<ParameterName>_<MethodName>()`
51+
A `Setup` and `Verify` methods will be generated for each public method of the mocked type.
4652

4753
##### Demonstration
4854

@@ -62,35 +68,31 @@ you can do this
6268
```csharp
6369
/* -- Setup -- */
6470
// Default parameter is Any
65-
Setup_dependency_MakeString(name:"Yarin")
71+
_dependency.MakeString.Setup(name:"Yarin")
6672
.Returns<int>(n=> n.ToString());
6773

6874
// Any Not Implicitly assumed
69-
Setup_dependency_MakeString(Value<int>.Any,"Yarin")
75+
_dependency.MakeString.Setup(Value<int>.Any, "Yarin")
7076
.Returns<int>(n=> n.ToString());
7177

7278
/* -- Verify -- */
73-
Setup_dependency_MakeString(Value<int>.Any,"Yarin", Times.Once())
79+
_dependency.MakeString.Verify(Value<int>.Any, "Yarin", Times.Once())
7480
```
7581

7682
### Example
7783

7884
For This Code
7985

8086
```csharp
81-
// Class Being Tested
8287
public class TestedClass
8388
{
8489
private IDependency _dependency;
8590
private ILogger _logger;
8691

87-
public TestedClass(IDependency dependency, ILoggerFactory factory)
88-
{
89-
/* Code */
90-
}
92+
public TestedClass(IDependency dependency, ILoggerFactory factory) // c'tor
9193
}
92-
93-
// Test Fixture class
94+
```
95+
```csharp
9496
public partial class Test
9597
{
9698
[FillMocks]
@@ -104,15 +106,18 @@ The Generated Code Will Be
104106

105107
```csharp
106108
public partial class Test
107-
{
108-
private Mock<IDependency> _dependencyMock;
109-
private Mock<ILoggerFactory> _factoryMock;
110-
111-
private TestedClass Build()
112109
{
113-
_dependencyMock = new Mock<IDependency>();
114-
_factoryMock = new Mock<ILoggerFactory>();
115-
return new TestedClass(_dependencyMock.Object, _factoryMock.Object);
110+
private Wrapper_IDependency _dependency;
111+
private Wrapper_ILoggerFactory _factory;
112+
113+
private TestedClass Build()
114+
{
115+
_dependency = new Wrapper_IDependency(new Mock<IDependency>());
116+
_factory = new Wrapper_ILoggerFactory(new Mock<ILoggerFactory>());
117+
return new TestedClass(_dependency.Mock.Object, _factory.Mock.Object);
118+
}
116119
}
117-
}
118120
```
121+
Example of Wrapper class with `[GenerateMockWrappers]` attribute [IDependency with wrappers](./TestsHelper.SourceGenerator.Tests/Sources/Wrapper.IDependency.WithWrappers.generated.cs)
122+
123+
Example of Wrapper class without mocked wrappers [IDependency without wrappers](./TestsHelper.SourceGenerator.Tests/Sources/Wrapper.IDependency.generated.cs)

Sample.Tests/Test.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ namespace Sample.Tests;
1111
[TestFixture]
1212
public partial class Test
1313
{
14-
[FillMocks]
15-
private TestedClass _testedClass;
14+
[FillMocks]
15+
private TestedClass _testedClass = null!;
1616

17-
1817
private readonly ILoggerFactory _defaultValueFactory = NullLoggerFactory.Instance;
1918

2019
[SetUp]
@@ -29,15 +28,14 @@ public void Setup_WithoutWrapper()
2928
// Arrange
3029
int numbrer = 1;
3130

32-
33-
_dependencyMock.Setup(dependency => dependency.MakeString(It.IsAny<int>()))
31+
_dependency.Mock.Setup(dependency => dependency.MakeString(It.IsAny<int>()))
3432
.Returns<int>((number) => number.ToString());
3533

3634
// Act
3735
string result = _testedClass.VeryComplicatedLogic(numbrer);
3836

3937
// Assert
40-
_dependencyMock.Verify(dependency => dependency.MakeString(2), Times.Once);
38+
_dependency.Mock.Verify(dependency => dependency.MakeString(2), Times.Once);
4139
Assert.That(result, Is.EqualTo("2"));
4240
}
4341

@@ -47,15 +45,14 @@ public void Setup_WithWrapper()
4745
// Arrange
4846
int number = 1;
4947

50-
51-
Setup_dependency_MakeString()
48+
_dependency.MakeString.Setup()
5249
.Returns<int>(n => n.ToString());
5350

5451
// Act
5552
string result = _testedClass.VeryComplicatedLogic(number);
5653

5754
// Assert
58-
Verify_dependency_MakeString(2, Times.Once());
55+
_dependency.MakeString.Verify(2, Times.Once());
5956
Assert.That(result, Is.EqualTo("2"));
6057
}
6158
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq.Expressions;
4+
using Moq;
5+
using NUnit.Framework;
6+
using TestsHelper.SourceGenerator.MockWrapping.Tests.Expressions;
7+
8+
namespace TestsHelper.SourceGenerator.MockWrapping.Tests;
9+
10+
[TestFixture]
11+
public class CyberTests
12+
{
13+
private ExpressionComparison _expressionComparison = null!;
14+
15+
[OneTimeSetUp]
16+
public void Setup()
17+
{
18+
_expressionComparison = new ExpressionComparison();
19+
}
20+
21+
[Test]
22+
public void CreateExpressionFor_GivenAnyValue_CallItAny()
23+
{
24+
// Arrange
25+
Value<int> anyValue = Value<int>.Any;
26+
var expectedMethodCallExpression = GetLambdaBody<MethodCallExpression>(() => It.IsAny<int>());
27+
28+
// Act
29+
Expression actualExpression = Cyber.CreateExpressionFor(anyValue);
30+
31+
// Assert
32+
_expressionComparison.AssertEquals(actualExpression, expectedMethodCallExpression);
33+
}
34+
35+
[Test]
36+
public void CreateExpressionFor_GivenValue_CallItIs()
37+
{
38+
// Arrange
39+
Value<int> value = 5;
40+
var expectedMethodCallExpression = GetLambdaBody<MethodCallExpression>(() => It.Is(5, EqualityComparer<int>.Default));
41+
42+
// Act
43+
Expression actualExpression = Cyber.CreateExpressionFor(value);
44+
45+
// Assert
46+
_expressionComparison.AssertEquals(actualExpression, expectedMethodCallExpression);
47+
}
48+
49+
[Test]
50+
public void UpdateExpressionWithParameters_OnAllParameterNull_PatchExpressionToUseItAny()
51+
{
52+
// Arrange
53+
var arguments = new List<Expression> {
54+
Cyber.CreateExpressionFor(Value<int>.Any),
55+
Cyber.CreateExpressionFor(Value<string>.Any),
56+
};
57+
58+
Expression<Action> method = () => MockMethod(Cyber.Fill<int>(), Cyber.Fill<string>());
59+
Expression<Action> expectedExpression = () => MockMethod(It.IsAny<int>(), It.IsAny<string>());
60+
61+
// Act
62+
Expression<Action> patchedExpression = Cyber.UpdateExpressionWithParameters(method, arguments);
63+
64+
// Assert
65+
_expressionComparison.AssertEquals(patchedExpression, expectedExpression);
66+
}
67+
68+
[Test]
69+
public void UpdateExpressionWithParameters_OnSomeAnyAndValue_PatchExpressionToUseItAnyOrItIs()
70+
{
71+
// Arrange
72+
var arguments = new List<Expression> {
73+
Cyber.CreateExpressionFor<int>(10),
74+
Cyber.CreateExpressionFor(Value<string>.Any),
75+
};
76+
77+
Expression<Action> method = () => MockMethod(Cyber.Fill<int>(), Cyber.Fill<string>());
78+
Expression<Action> expectedExpression = () => MockMethod(It.Is(10, EqualityComparer<int>.Default), It.IsAny<string>());
79+
80+
// Act
81+
Expression<Action> patchedExpression = Cyber.UpdateExpressionWithParameters(method, arguments);
82+
83+
// Assert
84+
_expressionComparison.AssertEquals(patchedExpression, expectedExpression);
85+
}
86+
87+
private void MockMethod(int age, string name)
88+
{
89+
90+
}
91+
92+
private static T GetLambdaBody<T>(Expression<Action> expression) where T : Expression => (T) expression.Body;
93+
}

0 commit comments

Comments
 (0)