Code Monkey home page Code Monkey logo

aspnetcore-easy-testing's Introduction

AspNetCore.EasyTesting

Test library for integration test make easy and this library is fully tested!

banner

Build And Test Nuget Nuget GitHub commit activity

Features

  • Replace InMemoryDb Easily
  • Replace internal service to your own object.
  • Mock/Fake internal service using by Moq, FakeItEasy, NSubstitute
  • Provide build api for writing testing code declarative.
  • Getting/Using service after init the test service.
  • Provide hooks like SetupFixture, Configure* Methods.
  • Fake Authentication

Getting Start!

First of all, you have to install this package like below in your project.

dotnet add packge AspNetCore.EasyTesting

And you can create SUT(Short word of System Under Test) object of your Startup class.

using var sut = new SystemUnderTest<Startup>(); // That's all!

If you want to replace your own services to fake service and check response data. Write code like below.

sut.Replace<IYourOwnService>(new FakeService());

var client = sut.CreateHttpClient();

var response = await client.GetAsync("path/to/your/api");

resopnse.ShouldBeOk<YourApiResponse>(apiResponse => {
    apiResponse.Field.Should().NotBeEmpty();
});

And this framework is not depends on ANY test framework. What you want, you can use this library for writing integration test easily! :')

Replace DbContext to In-Memory DbContext.

If you want to change your DbContext connection with in-memory db-context? You don't need to separate environment in your api project! Just add package and call ReplaceInMemoryDbContext<TDbContext> or ReplaceSqliteInMemoryDbContext<TDbContext>!

dotnet add package AspNetCore.EasyTesting.EntityFrameworkCore 
sut.ReplaceInMemoryDbContext<SampleDb>() // Replace your registered both `DbContextOptions<TDbContext>` and `DbContextOptions`
    .SetupFixture<SampleDb>(async db =>
    {
        db.SampleDataEntities.Add(new SampleDataEntity());
        await db.SaveChangesAsync();
    }); 

Note that if there are no any specific database name about ReplaceInMemoryDbContext, the database name is assigned Guid.NewGuid().ToString() to prevent fail test when parallel test run environment.

Mock/Fake you owned services!

If you want to replace your own service with mock/fake object.

dotnet add package AspNetCore.EasyTesting.[Moq/FakeItEasy/NSubstitute]

Note that, how many you call replace fake/mock service method, this create library only once and re-use fake/mock object. that mean, you can write mocking chaining code elegantly. ;)

Moq

// All cases is same!
var mockService = sut.MockService<ISampleService>();
sut.MockService<ISampleService>(out var mock);
sut.MockService<ISampleService>(mock => mock
   .Setup(service => service.GetSampleDate())
   .Returns("Action mocked!"))

// Verify helper
sut.VerifyCallOnce<ISampleService>(service => service.GetSampleDate());
sut.VerifyCall<ISampleService>(service => service.GetSampleDate(), Times.Once());

FakeItEasy

// Dummy service
sut.ReplaceDummyService<ISampleService>();

// Replace fake service
var fakeService = sut.FakeService<ISampleService>();
sut.FakeService<ISampleService>(out var fakeService);
sut.FakeService<ISampleService>(service => A
   .CallTo(() => service.GetSampleDate())
   .Returns("MockedData"))

// Take registered fake service
var fakeService = sut.GetFakeService<ISampleService>();
sut.UseFakeService<ISampleService>(service => A.CallTo(() => service.GetSampleDate()).MustHaveHappend());

NSubstitute

// Replace service with substitute
sut.ReplaceWithSubstitute<ISampleService>(out var mockedService);
sut.ReplaceWithSubstitute<ISampleService>(substitute => /* setup */);
var substitute = sut.ReplaceWithSubstitute<ISampleService>();

// Verify
sut.GetSubstitute<ISampleService>().Received().GetSampleDate();
sut.UseSubstitute<ISampleService>(substitute => substitute.Received().GetSampleDate());

Replace Pre-Registered application service with new service.

sut.ReplaceService<ISampleService, FakeSampleServic>();
sut.ReplaceService<ISampleService>(new FakeSampleService()); // It will be always registered as singleton.

Use internal service object for verifying test is successfully working.

Use SystemUnderTest.UsingServiceAsync or SystemUnderTest.UsingService methods for use internal service.

await sut.UsingServiceAsync<ISampleService>(async service => {
    var updated = await service.GetSameplAsync(OriginalFixtureId);
    updated.Data.Should().Be("Newer Sample Data");
});

Verify lifetime of service registration.

Use SystemUnderTest.VerifyRegisteredLifeTimeOfService to verify to register your application service lifetime rightly.

var sut = new SystemUnderTest<Startup>();

sut.VerifyRegisteredLifeTimeOfService<ISampleService>(ServiceLifetime.Scoped);

Use delegate methods of IWebHostBuilder for customizing by your hand! ๐Ÿ‘‹

SystemUnderTest provide delegate methods of IWebHostBuilder to allow fully customization of your way. Check out below methods.

  • SystemUnderTest.ConfigureServices
  • SystemUnderTest.ConfigureAppConfiguration
  • SystemUnderTest.UseSetting
  • SystemUnderTest.SetupWebHostBuilder

Fake authentication layer of ASP.NET Core

We can do fake authentication handler easily through call few method. But It's not recommended for custom complex implementation of authentication process.

usnig var sut = new SystemUnderTest<Startup>();

// this replace disable defualt original authentication handler with fake authentication handler  
var httpClient = sut.NoUserAuthentication()
    // .AllowAuthentication("Bearer", new ClaimsPrincipal(/* configure test user principal */)) for faking specific authentication scheme.
    // .DenyAuthentication() for test unauthorized call
    .CreateClient();

// Now you can call any authorized actions

This library provide you four type methods.

  • NoUserAuthentication : When server couldn't find authentication related parts(Cookie, Token, JWT ... etc) from http call.
  • DenyAuthentication : When server found authentication related parts But it's invalid
  • AllowAuthentication : When server found valid authentication related parts and can make IPrincipal
  • FakeAuthentication : What you want, just call this method and provide valid ticket or principal instance.

If you don't provide sheme parameter, it will use DefaultScheme to fake that is already configured in Startup.cs by your hand. ๐Ÿ‘‹

services.AddAuthentication("Bearer") // "Bearer" scheme is default authentication scheme.

Note that if you want to use your own IIdentity when fake authentication handler for some scheme. IIdentity.IsAuthenticated should return true. if it is not, every call is denied by ASP.NET Core authentication middleware.

And more use cases..

Visit this library test project. You can see every cases to use this library.

LICENSE

MIT License

Copyright (c) 2020 WDWWW

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

aspnetcore-easy-testing's People

Contributors

enif-lee avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.