https://github.com/canerpatir/commonfixtures
A toolkit contains essential test fixtures for .net core and asp.net core projects.
https://github.com/canerpatir/commonfixtures
aspnet-core nunit selenium tdd unit-testing xunit
Last synced: 4 months ago
JSON representation
A toolkit contains essential test fixtures for .net core and asp.net core projects.
- Host: GitHub
- URL: https://github.com/canerpatir/commonfixtures
- Owner: CanerPatir
- Created: 2020-05-27T15:14:38.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-03-27T09:06:10.000Z (over 3 years ago)
- Last Synced: 2024-04-28T22:34:40.932Z (over 1 year ago)
- Topics: aspnet-core, nunit, selenium, tdd, unit-testing, xunit
- Language: C#
- Homepage:
- Size: 84 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
CommonFixtures
========

[](https://img.shields.io/codecov/c/github/CanerPatir/CommonFixtures?token=OSKYBSA9KW)

Common fixture is a toolkit contains essential test fixtures for .net core and asp.net core test projects. CommonFixtures aims
to reduce your preparing test suite effort for common testing concerns and supplying ready to use testing infrastructure.
CommonFixtures can be used independently from testing framework. You can prefer any kind of dotNet testing framework like xUnit, nUnit etc.
|Supported .Net Core Versions|
|--------------|
|.netocreapp3.1|
|.netocreapp3.0|
Ready to use fixtures
========
CommonFixtures supplies some base classes to supply underlying fixtures for your test suite. These are as below;
* [BaseTest](#basetest)
* [WithIoC](#withioc)
* [WithHost](#withhost)
* [WithWebApp](#withwebapp)
* [WithEfCore](#withefcore)
* [WithWebAppAndEfCore](#withwebappandefcore)
* Selenium support for WithWebApp and WithWebAppAndEfCore fixtures
## BaseTest
Contains basic mocking and stubbing methods to supply standard DSL for all tests. (It uses FakeItEasy library for faking and AutoFixture for data generation internally)
* Stubbing demo
```csharp
public class ProductServiceTests : BaseTest
{
private readonly ProductService _sut;
private readonly IProductRepository _mockRepository;
public ProductServiceTests()
{
_mockRepository = Mock();
_sut = new ProductService(_mockRepository);
}
// with your favourite testing tool xUnit, nunit ... etc.
// [Fact]
// [Test]
public async Task Should_Created_Product()
{
// Given
var givenTitle = Random();
var givenPrice = Random();
var expectedId = Random();
StubAsync(() => _mockRepository.CreateProduct(ArgMatches(x => x.Title == givenTitle && x.Price == givenPrice), ArgIgnore()), expectedId);
// When
var id = await _sut.CreateProduct(givenTitle, givenPrice);
// Then
Assert.Equal(expectedId, id);
}
}
```
* Verification demo
```csharp
public async Task Should_Call_Repo_Once()
{
// Given
var givenTitle = Random();
var givenPrice = Random();
// When
await _sut.CreateProduct(givenTitle, givenPrice);
// Then
Verify(() => _mockRepository.CreateProduct(ArgMatches(x => x.Title == givenTitle && x.Price == givenPrice), ArgIgnore()), numberOfTimes: 1);
}
```
## WithIoC
ServiceCollection fixture to keep your IoC logic afloat throughout the test.
```csharp
public class ProductServiceTest : WithIoC
{
protected override void ConfigureServices(IServiceCollection services)
{
services.MockAndRegister();
services.Register();
}
[Fact]
public async Task Should_Created_Product()
{
// Given
var givenTitle = Random();
var givenPrice = Random();
var mockRepository = GetService();
var sut = GetService();
// When
await sut.CreateProduct(givenTitle, givenPrice);
// Then
Verify(() => mockRepository.CreateProduct(ArgMatches(x => x.Title == givenTitle && x.Price == givenPrice), ArgIgnore()), numberOfTimes: 1);
}
}
```
* Also allows you to mock some dependencies of the system under test while leaving others as they are
```csharp
public class DependencyMockingTest : WithIoC
{
public class YourAwesomeService
{
public YourAwesomeService(IDependency1 dep1, IDependency2 dep2)
{
_dep1 = dep1;
_dep2 = dep2;
}
// ....
}
protected override void ConfigureServices(IServiceCollection services)
{
services.MockAndRegister();
services.Register();
// so mocked just dependency 1 and leaving second one as it is
}
// ....
}
```
## WithHost
Supplies test host for testing .net core hosted services (see: [.NET Core Hosted Services](https://docs.microsoft.com/tr-tr/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio))
```csharp
public class QueuedJobHostedServiceTests : WithHost
{
protected override void ConfigureServices(IServiceCollection services)
{
// adding your awesome hosted service
services.AddHostedService();
}
[Fact]
public async Task It_Should_Execute_Queued_Task()
{
// Arrange
var queueManager = GetService();
var counter = 0;
// Act
queueManager.EnqueueJob(() =>
{
Interlocked.Increment(ref counter);
});
// Assert
await Task.Delay(300);
Assert.Equal(1, counter);
}
}
```
## WithWebApp
Aspnet core test server fixture for integration testing scenarios
```csharp
public class MvcIntegrationTest : WithWebApp
{
protected override void ConfigureServices(IServiceCollection services)
{
// You can override or mock services that registered from Startup.cs before
}
[Fact]
public async Task Get_EndpointsReturnSuccessAndCorrectContentType()
{
// Arrange
var client = HttpClient;
// Act
var response = await client.GetAsync("/weatherforecast");
// Assert
response.EnsureSuccessStatusCode();
Assert.Equal("application/json; charset=utf-8",
response.Content.Headers.ContentType.ToString());
}
}
```
> :warning: Ensure _Microsoft.AspNetCore.Mvc.Testing_ package added to root of your test project before using this fixture.
## WithEfCore
* Supplies test fixture to test projects which use Entity Framework Core as persistence layer.
* CommonFixtures automatically replaces your existing ef core db context configuration with in memory sqlLite.
* Provides useful approach when you want to test your persistence logic like db model, entity validations, secend level cache, repository abstractions without mocking anything.
```csharp
public class ProductRepositoryTest : WithEfCore
{
[Fact]
public async Task Should_Persist_New_Created_Product()
{
// Arrange
Arrange(dbContext =>
{
// helper that pull the database to desired state before acting (optional)
});
var sut = new ProductRepository(DbContext);
// Act
var id = await sut.CreateProduct(Random(), CancellationToken.None);
// Assert
NewServiceScope(); // dispose all of services and recreate new one to simulate new scope like new http request
Assert.IsType(id);
Assert.NotEqual(default, id);
var createdProduct = Get(id);
Assert.NotNull(createdProduct);
}
}
```
## WithWebAppAndEfCore
* Combination of WithWebApp and WithEfCore
* In addition to the _WithEfCore_, starts test server up and running then replace db context which registered in the Startup.ConfigureServices method
* It is useful when you want to make test more complex application logic without mocking persistence layer
```csharp
// Automatically replaces your db context configuration specified in Startup.cs with in memory sqlLite
public class CreateProductCommandHandlerTest : WithWebAppAndEfCore
{
[Fact]
public async Task Should_Created_New_Product()
{
// Arrange
Arrange(dbContext =>
{
// you can use pull the database to desired state before acting
// dbContext.Categories.Add(Random());
});
var mediator = GetService();
// Act
var id = await mediator.Send(Random());
// Assert
NewServiceScope(); // dispose all of services and recreate new one to simulate new scope like new http request
Assert.IsType(id);
Assert.NotNull(Get(id));
}
}
```
## UI Testing With Selenium
* Make sure that following two dependencies are added to your test project.
```xml
```
```csharp
// see SampleWebApp Index.cshtml to see sut
public class MvcViewIntegrationTest : WithWebApp
{
protected override bool SeleniumEnabled => true;
protected override bool SeleniumHeadless => true; // you can make false to see chrome browser
[Fact]
public void Counter_Test()
{
// Arrange
WebDriverWait waitForElement = new WebDriverWait(Selenium, TimeSpan.FromSeconds(10));
waitForElement.Until(ElementIsVisible(By.Id("counter")));
var button = Selenium.FindElement(By.Id("btn"));
var counterSpan = Selenium.FindElement(By.Id("counter"));
// Act
Assert.Equal(0, int.Parse(counterSpan.Text));
button.Click();
// Assert
counterSpan = Selenium.FindElement(By.Id("counter"));
Assert.Equal(1, int.Parse(counterSpan.Text));
}
}
```