Hi, we are trying to write a set of integration tests to verify simple crud operations of an SfGrid using bUnit.
We have everything hooked up, but SfGrid is not to be invoking any operations on the CustomAdapter.
<SfGrid TValue="FtpDto" Toolbar="@(new List<string> { "Add", "Edit", "Delete" })">
<SfDataManager AdaptorInstance="@typeof(FtpDataManager)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
<GridColumns>
<GridColumn Field="@(nameof(FtpDto.FTPId))" IsPrimaryKey="true" />
<GridColumn Field="@(nameof(FtpDto.Description))" />
<GridColumn Field="@(nameof(FtpDto.Address))" />
</GridColumns>
<GridEvents TValue="FtpDto" />
<GridEditSettings Mode="EditMode.Dialog" AllowAdding="true" AllowEditing="true" AllowDeleting="true" Dialog="@EditDialogSettings">
<Template>
@{
var ftp = (context as FtpDto);
<FTPEditForm FTP="@ftp" />
}
</Template>
</GridEditSettings>
</SfGrid>
public class FtpDataManager : BaseDataManager<FtpDto>
{
public FtpDataManager(HttpClient httpClient) : base("ftp", httpClient)
{
}
}
public class FtpDataManager : BaseDataManager<FtpDto>
{
public FtpDataManager(IHttpClientFactory httpClient) : base("ftp", httpClient)
{
}
}
public abstract class BaseDataManager<TRequest> : DataAdaptor
{
private readonly string _controllerUrl;
private readonly IHttpClientFactory _httpClientFactory;
private readonly HttpClient _httpClient;
public BaseDataManager(string controllerUrl, IHttpClientFactory httpClientFactory) : base()
{
_controllerUrl = controllerUrl;
_httpClientFactory = httpClientFactory;
}
//[Inject]
//public HttpClient HttpClient { get; set; }
public override async Task<object> ReadAsync(DataManagerRequest dm, string additionalParam = null)
{
IEnumerable<TRequest> dataSource = await Get("Get");
if (dm.Search != null && dm.Search.Count > 0)
{
// Searching
dataSource = DataOperations.PerformSearching(dataSource, dm.Search);
}
if (dm.Sorted != null && dm.Sorted.Count > 0)
{
// Sorting
dataSource = DataOperations.PerformSorting(dataSource, dm.Sorted);
}
if (dm.Where != null && dm.Where.Count > 0)
{
// Filtering
dataSource = DataOperations.PerformFiltering(dataSource, dm.Where, dm.Where[0].Operator);
}
int count = dataSource.Count();
if (dm.Skip != 0)
{
//Paging
dataSource = DataOperations.PerformSkip(dataSource, dm.Skip);
}
if (dm.Take != 0)
{
dataSource = DataOperations.PerformTake(dataSource, dm.Take);
}
return dm.RequiresCounts ? new DataResult() { Result = dataSource, Count = count } : (object)dataSource;
}
public override async Task<object> InsertAsync(DataManager dataManager, object record, string additionalParam)
{
return await Post<TRequest, TRequest>(dataManager, $"AddOrUpdate", (TRequest)record);
}
public override async Task<object> UpdateAsync(DataManager dataManager, object record, string primaryColumnName, string additionalParam)
{
return await Post<TRequest, TRequest>(dataManager, $"AddOrUpdate", (TRequest)record);
}
public override async Task<object> RemoveAsync(DataManager dataManager, object primaryColumnValue, string primaryColumnName, string additionalParam)
{
string url = $"entity-api/{_controllerUrl}/{primaryColumnValue}";
HttpResponseMessage response = await dataManager.HttpClientInstance.DeleteAsync(url);
return await ProcessResponse<bool>(response);
}
private async Task<IEnumerable<TRequest>> Get(string method)
{
string url = $"entity-api/{_controllerUrl}/{method}";
HttpResponseMessage response = await _httpClientFactory.CreateClient(Options.DefaultName).GetAsync(url);
return await ProcessResponse<List<TRequest>>(response);
}
private async Task<TResponse> Post<TReq, TResponse>(DataManager dataManager, string method, TReq request)
{
string url = $"entity-api/{_controllerUrl}/{method}";
string req = JsonSerializer.Serialize(request);
System.Diagnostics.Debug.WriteLine(req);
HttpResponseMessage response = await dataManager.HttpClientInstance.PostAsJsonAsync(url, request);
return await ProcessResponse<TResponse>(response);
}
private static async Task<T> ProcessResponse<T>(HttpResponseMessage response)
{
string responseString = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return JsonSerializer.Deserialize<T>(responseString);
}
throw ThrowException(responseString);
}
private static ApiException ThrowException(string responseString)
{
ErrorResponse errorResponse = JsonSerializer.Deserialize<ErrorResponse>(responseString);
return new ApiException(errorResponse.Title)
{
Title = errorResponse.Title,
Detail = errorResponse.Detail,
Errors = errorResponse.Errors,
Status = errorResponse.Status
};
}
}
public class FtpEditPageTest
{
private WireMockServer _wireMockServer;
public FtpEditPageTest()
{
_wireMockServer = WireMockServer.Start();
}
public void Dispose()
{
_wireMockServer.Stop();
}
[Fact]
public void GetTest()
{
var ftpDtos = new List<FtpDto>
{
new FtpDto
{
FTPId = "Ftp",
Description = "Test",
Address = "localhost",
Port = 21,
UserName = "test",
Password = "test",
SSH = false,
SSL = false,
ImplicitSSL = false,
ConnectionType = FTPConnectionType.Active
}
};
var testContext = new TestContext();
testContext.Services.AddOptions();
testContext.Services.AddHttpClient(Options.DefaultName, a => a.BaseAddress = new Uri(_wireMockServer.Urls[0]));
testContext.Services.AddScoped<FtpDataManager>();
testContext.Services.AddSyncfusionBlazor();
_wireMockServer.Given(Request.Create()
.WithPath("entity-api/ftp/Get")
.UsingGet())
.RespondWith(Response.Create().WithBodyAsJson(ftpDtos));
var cut = testContext.RenderComponent<FTPPage>();
var grid = cut.FindComponent<SfGrid<FtpDto>>();
}
}
Following up here - we added a Task.Delay and our methods are called, we return data, but Datasource, and any data methods are all null.
Hi Nick,
Based on your query, we would like to inform you that BUnit is
primarily designed for testing Blazor components and their interactions.
Therefore, it is not recommended to use BUnit for SfDataManger
We suggest you try using MockTesting while using DataManager.
Kindly refer the below documentation for your reference.
Reference: https://bunit.dev/docs/test-doubles/mocking-httpclient.html
We have discussed a similar query in the below forums. Kindly refer the below thread for additional information.
https://www.syncfusion.com/forums/166936/unable-to-mock-the-response-to-an-sfdatamanager
https://www.syncfusion.com/forums/159330/unit-tests
https://www.syncfusion.com/forums/186956/unit-test-a-grid
Regards,
Prathap Senthil