JustMock supports .ReturnsAsync()
when arranging standard mocks, however I am unable to find a way to get this same behavior when Automocking with a MockingContainer<T>
.
A solution I've found is to wrap the return value in Task.FromResult<T>()
. This fulfills the expected Task<T>
return type of the async function, however the syntax is a bit clunky.
service
.Arrange<IRepository>(r => r.SomeAsyncMethod("input"))
.Returns(Task.FromResult<ISomeModel>(resultModel));
Ideally, I would like to avoid building the Task<T>
return values manually and just rely on .ReturnsAsync()
to handle the conversion.
service
.Arrange<IRepository>(r => r.SomeAsyncMethod("input"))
.ReturnsAsync(resultModel);
It's possible the APIs just aren't there, but I want to ensure I'm not just missing some special syntax to get it working.
I have a test case to test my EF repository getallasync call as follows:
// Arrange
var systemsData = new List<SystemEntity>
{
new SystemEntity { SystemId = 1, Full_Year_Standings = true, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now },
new SystemEntity { SystemId = 2, Full_Year_Standings = false, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now },
new SystemEntity { SystemId = 3, Full_Year_Standings = true, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now }
};
var mockContext = Mock.Create<BetCenterContext>(Behavior.Loose);
Mock.Arrange(() => mockContext.Set<SystemEntity>()).ReturnsCollection(systemsData);
var systemRepository = new SystemRepository(mockContext);
// Act
var result = await systemRepository.GetAllAsync();
Calling the following method:
public async Task<List<SystemEntity>> GetAllAsync()
{
var collToReturn = await _context.Set<SystemEntity>().ToListAsync();
return collToReturn;
}
The arranged mock returns a null result and throws InvalidOperationException - The source 'IQueryable' doesn't IAsyncEnumerable...'
How do I arrange the mock to return the correct value?
We are adding UI unit tests for our Blazor project and diving into evaluating your JustMock and your testing framework. i am trying to create a test that invokes AddReleaseAsync method, but nothing that I have tried avoids a compile error, that I am showing below. We have a form that has a Blazor grid, initially populated with the data returned from GetReleasesAsync method, and then we add a new row using AddReleaseAsync expecting to see an additional data row. A simple test that uses only GetReleasesAsync method and checks that 2 data rows are returned works fine. But I can't compile the below test for adding a row. How do I mock an async method returning an anonymous type? We are using a pattern returning <string message, IEnumerable<T> data> quite extensively in our services to pass info/error Message and Data to the UI. Is it possible to mock the AddReleaseAsync and if so, how ?
P.S. I understand that test is not quite 'complete', but I can't get past the compile error to properly write the test
Given this interface
public interface IApiLogic
{
Task<IEnumerable<Release>> GetReleasesAsync(); // gets all data
Task<(string Message, IEnumerable<Release>? Releases)> AddReleaseAsync(Release release);
}
And the below test method,
[TestMethod]
public void CanAddnewRelease()
{
// Arrange
var apiMock = Mock.Create<IApiLogic>();
Mock.Arrange(() => apiMock.GetReleasesAsync()).ReturnsAsync(DummyReleases(2));
var response = new { Message = "ok", Releases = DummyReleases(3)};
// 1. Tried this (and many other things, but always get a similar error)
Mock.Arrange(() => apiMock.AddReleaseAsync(Arg.IsAny<Release>())).ReturnsAsync(response);
/* I get compile error for the above line
Error CS1503 Argument 2: cannot convert from '<anonymous type: string Message, System.Collections.Generic.IEnumerable<SDCSSPxte.Shared.Entities.Release> Releases>' to 'System.Func<(string Message, System.Collections.Generic.IEnumerable<SDCSSPxte.Shared.Entities.Release> Releases)>'
*/
// 2. Tried this
Mock.Arrange(() => apiMock.AddReleaseAsync(Arg.IsAny<Release>())).Returns(Task.FromResult<(string Message, IEnumerable<Release>? Releases)>(response));
/* I get compile error on the above line
Error CS1503 Argument 1: cannot convert from '<anonymous type: string Message, System.Collections.Generic.IEnumerable<SDCSSPxte.Shared.Entities.Release> Releases>' to '(string Message, System.Collections.Generic.IEnumerable<SDCSSPxte.Shared.Entities.Release>? Releases)'
*/
var ctx = new Bunit.TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.Services.AddSingleton<IApiLogic>(apiMock);
ctx.Services.AddTelerikBlazor();
var rootComponentMock = Mock.Create<TelerikRootComponent>();
// Act
var cut = ctx.RenderComponent<SDCSSPxte.Client.Pages.Admin.Release>(parameters => parameters.AddCascadingValue<TelerikRootComponent>(rootComponentMock));
var addButton = cut.FindAll(".k-button-text")[0];
addButton.Click();
// Assert
var dataRows = cut.FindAll("tbody tr");
dataRows.Count.Should().Be(3);
dataRows[0].ChildNodes.FirstOrDefault(n => n.TextContent.Trim() == "ReleaseComment for r1").Should().NotBeNull();
dataRows[1].ChildNodes.FirstOrDefault(n => n.TextContent.Trim() == "ReleaseComment for r2").Should().NotBeNull();
dataRows[2].ChildNodes.FirstOrDefault(n => n.TextContent.Trim() == "ReleaseComment for r3").Should().NotBeNull();
}
// You should be able to infer what the Release class is, it is in a separate project, SDCSSPxte.Shared.Entities. namespace)
private List<Release> DummyReleases (int count)
Hi Team
We tried executing justMock test cases in command prompt using justMock Console (licensed), dotCover and xUnit, but justMock Test execution failed and gave the error "System.InvalidProgramException : Common Language Runtime detected an invalid program."
The command we use to execute is as follows:
start /wait "" "{PATH}\JustMock\Libraries\Telerik.JustMock.Configuration.exe" /link "dotCover"
"{PATH}\JustMock\Libraries\Telerik.JustMock.Console.exe" runadvanced --profiler-path-64 "{PATH}\JustMock\Libraries\CodeWeaver\64\Telerik.CodeWeaver.Profiler.dll" --command "{PATH}\JetBrains.dotCover.CommandLineTools.2021.1.3\dotCover.exe" --command-args "cover --reporttype=html --output=CodeCoverage\\index.html --targetexecutable=\"{PATH}\xunit.runner.console.2.4.1\tools\net472\xunit.console.exe\" -- \"{PATH}\{PATH_OF_JUSTMOCK_TEST_DLL}\""
start /wait "" "{PATH}\JustMock\Libraries\Telerik.JustMock.Configuration.exe" /unlink "dotCover"
Attaching the log and test code.