Create Project
- Open git Bash and type
dotnet new sln -o CloudCustomers
- Enter the CloudCustomers folder and type
dotnet new webapi -o CloudCustomer.API
,dotnet new xunit -o CloudCustomers.UnitTests
anddotnet sln add **/*.csproj
Install Nuget Packages
- Install Moq and FluentAssertions
Test 1 : Trial
Change File Structure
- CloudCustomers.API/Controllers/UserController.cs
- CloudCustomers.UnitTests/Systems/Controllers/TestUsersController.cs
Test Annotations
[Fact]
attribute declares a test method that’s run by the test runner.[Theory]
represents a suite of tests that execute the same code but have different input arguments.[InlineData]
attribute specifies values for those inputs.
Test Structure
- Arrange: inputs and targets. Arrange steps should set up the test case. For examples, any objects or special settings, to prep a database, to log into a web app. Handle all of these operations at the start of the test.
- Act: on the target behavior. Act steps should cover the main thing to be tested. This could be calling a function or method, calling a REST API, or interacting with a web page. Keep actions focused on the target behavior.
- Assert: expected outcomes. Act steps should elicit some sort of response. Assert steps verify the goodness or badness of that response. Sometimes, assertions are as simple as checking numeric or string values. Other times, they may require checking multiple facets of a system. Assertions will ultimately determine if the test passes or fails.
Open Test Exploler
- [View] - [Test Exploler]
Run Test
- Click
Run
- We call all passed test to green test.
Test 2: DIP
DIP(Dependency Inversion Principle) From SOLID
- Hihgh-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details.
- Details should depend on abstractions.
SOLID
- S: Single Responsibility Principle
- O: Open/Closed principle
- L: Liskov Substitution Principle
- I: Interface Segregation Principle
- D: Dependency Inversion Principle
Change File Structure
- CloudCustomers.API/Controllers/UsersController.cs
- CloudCustomers.API/Models/User.cs
- CloudCustomers.API/Models/Address.cs
- CloudCustomers.API/Services/UsersService.cs
- CloudCustomers.API/Program.cs
- CloudCustomers.UnitTests/Systems/Controllers/TestUsersController.cs
Dependency Injection
- For DIP, I used Dependency Injection for
UsersService
. - And then, I created
mockUserService
as a object and make it to instance forUsersService
.
Mock
- Initializes an instance of the mock with Moq.MockBehavior.Default behavior.
Arrange
- Setup(): Specifies a setup on the mocked type for a call to a method.
- ReturnAsync(): Specifies the value to return from an asynchronous method.
Assert
- Verify(): Verifies that a specific invocation matching the given expression was performed on the mock. Use in conjunction with the default Moq.MockBehavior.Loose.
- Times.Once(): Specifies that a mocked method should be invoked exactly one time.
FluentAssertions
- Should(): Returns an FluentAssertions.Numeric.NullableNumericAssertions`1 object that can be used to assert the current nullable System.Int32.
- Be(): Asserts that the integral number value is exactly the same as the expected value.
- BeOfType(): Asserts that the object is of the specified type T.
Run Test
Test 3: Fixtures
Change File Structure
- CloudCustomers.UnitTests/Fixtures/UsersFixture.cs
- CloudCustomers.UnitTests/Systems/Controllers/TestUsersController.cs
- On
Get_OnSuccess_ReturnsStatusCode200
andGet_OnSuccess_ReturnsListOfUsers
, addUsersFixtures
instead new object.
- On
Fixture
- Fixed state of objects used as baselines for test execution
Run Test
Test 4: Request
Change File Structure
- CloudCustomers.API/Config/UsersApiOptions.cs
- CloudCustomers.API/Services/UsersService.cs
- CloudCustomers.API/appsettings.json
- CloudCustomers.API/Program.cs
- Add
UserApiOptions
inConfigurationServices
function.
- Add
- CloudCustomers.UnitTests/Helpers/MockHttpMessageHandler.cs
- CloudCustomers.UnitTests/Systems/Services/TestUsersService.cs
HttpMessageHandler
- A base type for HTTP message handlers.
- I used this to verify HttpClient requests.
Endpoint
- IOptions
: Used to retrieve configured TOptions instances. - service.Configure
: Registers a configuration instance which TOptions will bind against. - builder.Configuration.GetSection: Get value from configuration providers for the application to compose. In this application, the configuration provider is appsetting.json.
Mock
- Protected(): Enable protected setups for the mock.
- ItExpr: Allows the specification of a matching condition for an argument in a protected member setup, rather than a specific argument value. “ItExpr” refers to the argument being matched.
Options
- Create(): Creates a wrapper around an instance of TOptions to return itself as an Microsoft.Extensions.Options.IOptions`1.