A typical ABP modular project usually consists of three main projects: `Application`, `Domain`, and `EntityFrameworkCore/MongoDB`. In these projects, we may provide many services that require unit testing.
Using abstract unit test classes involves first writing tests in the `Application` and `Domain` layers that are independent of the storage technology, ensuring the correctness of core business logic. These abstract tests are then implemented in `EntityFrameworkCore` or `MongoDB`. The benefits of this approach include:
1. **Reduced Coupling**: Core logic tests do not depend on specific storage technologies, so switching databases does not require rewriting test code.
2. **Better Isolation**: Focuses on verifying business logic correctness, avoiding interference from database operations.
3. **Increased Reusability**: The same abstract tests can be reused with different storage implementations.
4. **Easier Maintenance and Extensibility**: Different storage implementations can be extended independently without breaking existing tests.
5. **Faster and More Reliable Tests**: Reduces dependency on databases, making tests faster and more stable.
## How to migrate old unit tests to the new unit test structure
Assume our project name is `MyCompanyName.MyProjectName`.
### Changes to the `MyCompanyName.MyProjectName.Application.Tests` project:
1. Remove the `MyCompanyName.MyProjectName.Application.Tests` project's `MyProjectNameApplicationCollection` class.
2. Modify the `MyCompanyName.MyProjectName.Application.Tests` project's `MyProjectNameApplicationTestBase` class.
```csharp
public abstract class MyProjectNameApplicationTestBase<TStartupModule> : MyProjectNameTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
//...
}
```
3. Modify the `MyCompanyName.MyProjectName.Application.Tests` project's unit test classes to become abstract unit test classes, such as: `SampleAppServiceTests`.
```csharp
public abstract class SampleAppServiceTests<TStartupModule> : MyProjectNameApplicationTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
[Fact]
public async Task Initial_Data_Should_Contain_Admin_User()
{
//...
}
}
```
### Changes to the `MyCompanyName.MyProjectName.Domain.Tests` project:
1. Remove the `MyCompanyName.MyProjectName.Domain.Tests` project's `MyProjectNameDomainCollection` class.
2. Modify the `MyCompanyName.MyProjectName.Domain.Tests` project's `MyProjectNameDomainTestBase` class.
```csharp
public abstract class MyProjectNameDomainTestBase<TStartupModule> : MyProjectNameTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
//...
}
```
3. Modify the `MyCompanyName.MyProjectName.Domain.Tests` project's unit test classes to become abstract unit test classes, such as: `SampleDomainTests`.
```csharp
public abstract class SampleDomainTests<TStartupModule> : MyProjectNameDomainTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
[Fact]
public async Task Should_Set_Email_Of_A_User()
{
//...
}
}
```
4. Modify the `MyCompanyName.MyProjectName.Domain.Tests` project's `csproj` and module class. Remove references to `EntityFrameworkCore/MongoDB`.
public class EfCoreSampleDomainTests : SampleDomainTests<MyProjectNameEntityFrameworkCoreTestModule>
{
//...
}
```
We also need to modify the project's dependencies and module class, which should directly or indirectly reference the `Application` and `Domain` test projects.
public class MyProjectNameEntityFrameworkCoreTestModule : AbpModule
{
//...
}
```
### Changes to the `MyCompanyName.MyProjectName.MongoDB.Tests` project (skip this step if not using MongoDB):
Like the `EntityFrameworkCore` project, we need to create implementation classes for all abstract unit tests and modify the project's dependencies and module class.
public class MyProjectNameWebTestModule : AbpModule
{
//...
}
```
We no longer need the `MyProjectNameWebCollection` class in this project. Please delete it and use `[Collection(MyProjectNameTestConsts.CollectionDefinitionName)]` instead.
## Conclusion
This is our new unit test structure. Decoupling unit tests from storage technologies ensures the independence of business logic and allows easy switching between storage implementations. Abstract unit test classes improve test reusability, maintainability, and efficiency, reducing refactoring costs and providing flexibility for future tech updates.
@ -50,6 +50,12 @@ This is the recommended approach, since it automatically finds all missing texts
If you want to make a change on a specific resource file, you can find the file yourself, make the necessary change (or create a new file for your language) and send a pull request on GitHub.
### Commercial Modules
The commercial modules are not open source, and their localization files are not available in the public repository. The open-source module, `Account`, and the commercial module, `Account.Pro`, may have different translations.
If you would like to translate a commercial module, please [create an issue](https://github.com/abpframework/abp/issues/new) on Github, and we will provide the necessary files (`abp-translation.json` for one or all modules).
## Bug Report
If you find any bug, please [create an issue on the Github repository](https://github.com/abpframework/abp/issues/new).
@ -4,6 +4,8 @@ This document introduces how to configure `OpenIddict` in the `AuthServer` proje
There are different configurations in the `AuthServer` project for the `Development` and `Production` environments.
> If your solution does not include a project named `.AuthServer`, it means that you might have another project that depends on `AbpAccountPublicWebOpenIddictModule`. The project name can be `MyProject`, `MyProject.Web`, or `MyProject.HttpApi.Host`. They are both `Authentication Server` projects in that context.
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
@ -38,6 +40,8 @@ To avoid that, consider creating self-signed certificates and storing them in th
You can use the `dotnet dev-certs https -v -ep openiddict.pfx -p 00000000-0000-0000-0000-000000000000` command to generate the `openiddict.pfx` certificate.
> `openiddict.pfx` is just an example of a filename. You can use any filename for the pfx file.
> `00000000-0000-0000-0000-000000000000` is the password of the certificate, you can change it to any password you want.
> Also, please remember to copy `openiddict.pfx` to the [Content Root Folder](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvironment.contentrootpath?view=aspnetcore-7.0) of the `AuthServer` website.
`IgnoredUrls` is the only option. It is a list of ignored URLs prefixes. In the preceding example, all URLs starting with `/products` will be ignored for audit logging.
## AbpAspNetCoreAuditingUrlOptions
`AbpAspNetCoreAuditingUrlOptions` is the [options object](../fundamentals/options.md) to configure audit logging in the ASP.NET Core layer. You can configure it in the `ConfigureServices` method of your [module](../architecture/modularity/basics.md):
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
## 0.9.16 (2024-12-11)
> This version does not work for macOS, we are currently working on that manner.
* Added a new command for refreshing the previously runned C#/Js Proxies.
* Added kubernetes configurations to Blazor WebApp for Microservice Template.
* Handled multiple dbcontexts for ef core migration operations.
* Made enhancements for dynamic localization feature in Microservice Template.
* Upgraded LeptonX Theme package versions to `4.0.2`.
If you run the ABP Suite with ABP CLI, then it will open in your default browser. Do not close the command line window until you finish your work, otherwise the Suite will not function. When you finish your work, you can return to the command line and press `CTRL+C` to close the Suite.
Remember that, first access to the Suite requires to have an active internet connection, so make sure you are connected to the internet.
Remember that, first access to the Suite requires to have an active internet connection, so make sure you are connected to the internet.
## Starting ABP Suite in Different Port
ABP Suite runs at port 3000 by default. If you want to run the ABP Suite in a different port, you can choose one of the following options:
1. You can pass the `--AbpSuite:ApplicationUrl` commandline parameter to run in a different port:
2. Update the `ApplicationUrl` in the _appsettings.json_ file of the dotnet tools directory (_%USERPROFILE%\.dotnet\tools\.store\volo.abp.suite\9.0.0\volo.abp.suite\9.0.0\tools\net9.0\any\appsettings.json_):

> **Note:** Also, you can use this file to configure ABP Suite options.
@ -135,7 +135,7 @@ public abstract class EfCoreRuntimeDatabaseMigratorBase<TDbContext> : ITransient
throw;
}
Logger.LogWarning($"{ex.GetType().Name} has been thrown. The operation will be tried {maxTryCount} times more. Exception:\n{ex.Message}. Stack Trace:\n{ex.StackTrace}");
Logger.LogWarning(ex,$"{ex.GetType().Name} has been thrown. The operation will be tried {maxTryCount} times more.");