Testing¶
You can test your plugin without starting HydroSym using the PluginTestHost class from the SDK or the HydroSymPluginTester CLI tool.
Unit testing with PluginTestHost¶
PluginTestHost drives your plugin class directly — no DLL loading, no JSON serialization — making it fast and debuggable.
Add the test package:
Basic test structure¶
using PARO.HydroSym.PluginSDK.Testing;
using Xunit;
public class AcmeErpPluginTests : IDisposable
{
private readonly PluginTestHost _host;
public AcmeErpPluginTests()
{
_host = new PluginTestHost(new AcmeErpPlugin());
_host.Initialize(new InitializeRequest
{
HydroSymVersion = "2025.55.0.0",
ConfigPath = "testdata/acme-test.ini",
HydroSymDataPath = "C:\\ProgramData\\HydroSym",
MainWindowHandle = 0,
WindowsUser = "testuser",
});
}
public void Dispose() => _host.Finalize_();
}
Testing GetInfo¶
[Fact]
public void GetInfo_ReturnsCorrectApiVersion()
{
var info = _host.GetInfo();
Assert.Equal(1, info.ApiVersion);
Assert.Contains("getComponentParameters", info.Capabilities);
}
[Fact]
public void GetInfo_HasSearchMenuItem()
{
var info = _host.GetInfo();
var searchItem = info.Menus?.FirstOrDefault(m => m.Id == "acme-search");
Assert.NotNull(searchItem);
Assert.Equal("component", searchItem!.ResultType);
}
Testing GetComponentParameters¶
[Fact]
public void GetComponentParameters_KnownValve_ReturnsReleasedStatus()
{
var response = _host.GetComponentParameters(new GetComponentParametersRequest
{
ArticleCode = "HV-301",
});
Assert.Equal("HV-301", response.ArticleCode);
Assert.Equal("released", response.Status);
Assert.Equal("EUR", response.Currency);
Assert.True(response.Price > 0);
}
[Fact]
public void GetComponentParameters_UnknownCode_ThrowsPluginException()
{
var ex = Assert.Throws<PluginException>(() =>
_host.GetComponentParameters(new GetComponentParametersRequest
{
ArticleCode = "UNKNOWN-999",
}));
Assert.Equal("NOT_FOUND", ex.ErrorCode);
}
Testing menu actions with a mock context¶
[Fact]
public void GetMenuItemState_NoOpenProject_DisablesCheckinButton()
{
var response = _host.GetMenuItemState(new GetMenuItemStateRequest
{
MenuItemIds = ["acme-checkin"],
Context = new PluginContext
{
ProjectPath = null, // no project open
},
});
Assert.False(response.States["acme-checkin"].Enabled);
}
Verifying JSON round-trips¶
The SDK includes helpers to verify that your response objects serialize correctly to the JSON the transport layer will send:
[Fact]
public void GetComponentParameters_ResponseSerializesCorrectly()
{
var response = _host.GetComponentParameters(new GetComponentParametersRequest
{
ArticleCode = "RV-101",
});
// Verify no serialization exceptions and round-trip fidelity
var json = PluginSerializer.Serialize(response);
var roundTripped = PluginSerializer.Deserialize<GetComponentParametersResponse>(json);
Assert.Equal(response.ArticleCode, roundTripped.ArticleCode);
Assert.Equal(response.Status, roundTripped.Status);
}
CLI testing with HydroSymPluginTester¶
HydroSymPluginTester.exe is a command-line tool that loads your native DLL and calls methods against it, displaying the raw JSON exchange. Use it to verify the built DLL behaves correctly before deploying.
# List all supported methods
HydroSymPluginTester.exe --dll AcmeErpPlugin.dll --call GetInfo
# Call GetComponentParameters
HydroSymPluginTester.exe --dll AcmeErpPlugin.dll --call GetComponentParameters \
--request "{\"articleCode\": \"HV-301\"}"
# Run all methods from a test script
HydroSymPluginTester.exe --dll AcmeErpPlugin.dll --script testcases.json
Test script format¶
[
{
"method": "GetInfo",
"request": {},
"expect": { "apiVersion": 1 }
},
{
"method": "GetComponentParameters",
"request": { "articleCode": "HV-301" },
"expect": { "status": "released", "currency": "EUR" }
},
{
"method": "GetComponentParameters",
"request": { "articleCode": "UNKNOWN-999" },
"expectError": { "code": "NOT_FOUND" }
}
]
The tester exits with code 0 if all assertions pass, 1 otherwise — suitable for use in CI pipelines.