Tutorial 05 01 Unit Testing Generated OData Services - Synergex/HarmonyCore GitHub Wiki

In this tutorial, you will add, generate, configure, and run unit tests for generated OData controllers and endpoints.
Before you begin, you must have an existing Harmony Core solution with generated OData services from Tutorial 2: Building a Service From Scratch. If your solution also includes custom authentication from Authentication via Custom Code, this will still apply.
You will add two projects: Services.Test, the generated unit test project and test host environment, and Services.Test.GenerateValues, a helper project that reads data and generates or updates test constants used by Services.Test.
-
Open your existing Harmony Core solution in Visual Studio and verify that it builds without errors.
-
In Visual Studio, select
Services.Hostin Solution Explorer, and then select Tools > Command Prompt (x64). -
At the command prompt, navigate to your solution root folder (the folder that contains your
.slnfile andCommon.props). Then setSolutionDirto that folder:set SolutionDir=%CD%\Note the trailing backslash, which is important.
-
Install or update the Harmony Core project templates:
dotnet new install Harmony.Core.ProjectTemplates -
Make sure the
harmonycore-utandharmonycore-utgtemplates are in the list of templates output by the previous command. -
Create the
Services.Testproject:dotnet new harmonycore-ut -o Services.Test -
Create the
Services.Test.GenerateValuesproject:dotnet new harmonycore-utg -o Services.Test.GenerateValues -
In Visual Studio, add both projects to the solution with Add > Existing Project:
-
Services.Test\Services.Test.synproj -
Services.Test.GenerateValues\Services.Test.GenerateValues.synproj
-
-
Save your changes by selecting File > Save All.
After adding the two template-based projects, align package and template versions across the solution.
-
Switch back to the command prompt and run these commands:
dotnet tool update -g Harmony.Core.CliTool harmonycore upgrade-latest -
When prompted after the second command, type
YESto continue. -
Return to Visual Studio. If prompted to reload modified projects, click Reload All.
Review the following project files and add or update entries only if they are missing or mismatched.
-
In
Services.synproj, confirm that the following package reference exists with the specified version:<PackageReference Include="Swashbuckle.AspNetCore"> <Version>6.9.0</Version> </PackageReference> -
In
Services.Test.synproj, confirm that the following exist with the specified versions:<PackageReference Include="Microsoft.OData.Core"> <Version>8.4.2</Version> </PackageReference> <PackageReference Include="Microsoft.OData.Edm"> <Version>8.4.2</Version> </PackageReference> <PackageReference Include="Microsoft.Spatial"> <Version>8.4.2</Version> </PackageReference>If they don't exist, add them after the
Microsoft.AspNetCore.ODatapackage reference. These explicit OData package references prevent assembly/version resolution conflicts at build and runtime. -
In
Services.Test.GenerateValues.synproj, confirm that the following exists with the specified version:<PackageReference Include="BitFaster.Caching"> <Version>2.5.4</Version> </PackageReference>If this doesn't already exist, add it in the first ItemGroup. This setting avoids older transitive
BitFaster.Cachingversions that can cause runtime failures in Harmony Core file I/O components. -
Rebuild the solution (Build > Rebuild Solution).
-
You may see this error:
"%DBL-F-NULPR, No primary files specified" for Services.Test. Ignore it at this point, but resolve any other build errors before continuing. -
If you get warnings about version resolution for package references, clean and rebuild
Services.Test.GenerateValues, clean and rebuildServices.Test, and then rebuild the solution.
-
Now enable unit-test generation in Harmony Core so that test scaffolding is included in the next regen.
-
Launch the Harmony Core CLI Tool GUI from the solution root:
harmonycore gui -
In the OData tab of the CLI Tool, set Enable unit tests to
Yes. (Double-click Enable unit tests and then, in the Enter new value screen, click the diamond icon to the right of Enable unit tests. The diamond will change to a checkmark. Click OK.) -
Save settings (File > Save).
With unit tests enabled, regenerate code so that the test project will have the required generated files.
- In the CLI Tool, run CodeGen > Regen. A window will open showing the files generated for the Enable unit tests option.
When unit tests are enabled, code generation updates Services.Test with files such as:
SelfHost.dblUnitTestEnvironment.dblTestConstants.Properties.dblDataGenerators\*.dblModels\*.dblUnitTests\*.dbl
The generated unit test methods use HttpClient and call your OData endpoints the same way an external client does.
After regeneration, make sure all newly created files are included in the Visual Studio projects.
- Do one of the following:
- In the CLI Tool, select CodeGen > Sync VS to add the newly generated files.
- In Visual Studio, use Add Existing Item to add the files that were generated for
Services.Test(listed above).
- Quit the CLI Tool.
Before generating constants or running tests, verify both test-related projects compile cleanly.
-
Build
Services.Testin Visual Studio and verify there are no errors. -
Build
Services.Test.GenerateValuesand verify there are no errors.
Next, create the test constants from your sample data and execute the generated test suite. The Services.Test.GenerateValues helper project includes GenerateTestValues.dbl, which reads test data files and creates or updates Services.Test\TestConstants.Values.json.
-
From the solution root, generate test constants by running the following at the command prompt:
dotnet run --project Services.Test.GenerateValues\Services.Test.GenerateValues.synprojThis command creates or updates
Services.Test\TestConstants.Values.json.You should see output similar to this (though "No JSON file found..." message appears only on the first run):
Processing file DAT:customers.ism - Opening DAT:customers.ism... - Counting records... No JSON file found here: C:\HarmonyCore\FullTut2withTestProjects_3\MyApi\Services.Test\TestConstants.Values.json Creating a new JSON file - Determining parameters for read by primary key... Processing file DAT:items.ism - Opening DAT:items.ism... - Counting records... - Determining parameters for read by primary key... Processing file DAT:orders.ism - Opening DAT:orders.ism... - Counting records... - Determining parameters for read by primary key... Processing file DAT:order_items.ism - Opening DAT:order_items.ism... - Counting records... - Determining parameters for read by primary key... Processing file DAT:vendors.ism - Opening DAT:vendors.ism... - Counting records... - Determining parameters for read by primary key... -
Change to the
Services.Testfolder:cd Services.Test -
Run unit tests by running the following at the command prompt:
dotnet test --no-build --logger "console;verbosity=detailed"You should see output similar to this:
Passed GetAllCustomers [684 ms] Passed GetAllCustomers_Expand_REL_Orders [391 ms] Passed GetAllCustomers_Expand_REL_Item [27 ms] Passed GetAllCustomers_Expand_All [235 ms] Passed GetOneCustomer [24 ms] Passed GetOneCustomer_Expand_REL_Orders [19 ms] Passed GetOneCustomer_Expand_REL_Item [7 ms] Passed GetOneCustomer_Expand_All [11 ms] Passed GetCustomer_ByAltKey_State [6 ms] Passed GetCustomer_ByAltKey_Zip [3 ms] Passed GetCustomer_ByAltKey_PaymentTerms [6 ms] Passed UpdateCustomer [236 ms] Passed GetAllItems [14 ms] Passed GetAllItems_Expand_REL_Vendor [28 ms] Passed GetAllItems_Expand_REL_OrderItems [701 ms] Passed GetAllItems_Expand_All [759 ms] Passed GetOneItem [6 ms] Passed GetOneItem_Expand_REL_Vendor [7 ms] Passed GetOneItem_Expand_REL_OrderItems [16 ms] Passed GetOneItem_Expand_All [13 ms] Passed GetItem_ByAltKey_VendorNumber [5 ms] Passed GetItem_ByAltKey_Color [5 ms] Passed GetItem_ByAltKey_Size [5 ms] Passed GetItem_ByAltKey_Name [3 ms] Passed UpdateItem [85 ms] Passed GetAllOrderItems [957 ms] Passed GetAllOrderItems_Expand_REL_Order [1 s] Passed GetAllOrderItems_Expand_REL_Item [757 ms] Passed GetAllOrderItems_Expand_All [1 s] Passed GetOneOrderItem [7 ms] Passed GetOneOrderItem_Expand_REL_Order [4 ms] Passed GetOneOrderItem_Expand_REL_Item [3 ms] Passed GetOneOrderItem_Expand_All [4 ms] Passed GetOrderItem_ByAltKey_ItemOrdered [4 ms] Passed GetOrderItem_ByAltKey_DateShipped [8 ms] Passed GetOrderItem_ByAltKey_InvoiceNumber [4 ms] Passed UpdateOrderItem [47 ms] Passed GetAllOrders [94 ms] Passed GetAllOrders_Expand_REL_OrderItems [2 s] Passed GetAllOrders_Expand_REL_Customer [222 ms] Passed GetAllOrders_Expand_All [2 s] Passed GetOneOrder [4 ms] Passed GetOneOrder_Expand_REL_OrderItems [9 ms] Passed GetOneOrder_Expand_REL_Customer [3 ms] Passed GetOneOrder_Expand_All [3 ms] Passed GetOrder_ByAltKey_CustomerNumber [3 ms] Passed GetOrder_ByAltKey_DateOrdered [2 ms] Passed GetOrder_ByAltKey_DateCompleted [6 ms] Passed UpdateOrder [48 ms] Passed GetAllVendors [4 ms] Passed GetAllVendors_Expand_REL_Items [15 ms] Passed GetAllVendors_Expand_All [15 ms] Passed GetOneVendor [4 ms] Passed GetOneVendor_Expand_REL_Items [9 ms] Passed GetOneVendor_Expand_All [3 ms] Passed GetVendor_ByAltKey_State [2 ms] Passed GetVendor_ByAltKey_Zip [2 ms] Passed GetVendor_ByAltKey_PaymentTerms [2 ms] Passed UpdateVendor [42 ms] Test Run Successful. Total tests: 59 Passed: 59 Total time: 15.2832 Seconds
If results differ from expected output, use these checks to resolve the most common setup and dependency issues.
-
If many tests fail immediately, run step 25 again to regenerate
TestConstants.Values.json. -
If build errors mention missing OData or caching assemblies, follow steps 13 through 16 to re-check settings.