For the sake of brevity, I've included a minimal example below. An async event MyEventAsync is defined in class MyClass. An event handler OnMyEventAsync is also defined.
public class MyClass
{
// Event.
public event Func<EventArgs, Task>? MyEventAsync;
}
// Event handler.
private Task OnMyEventAsync(EventArgs args) => Task.CompletedTask;
I then create a mock of MyClass and register the event handler OnMyEventAsync with the event MyEventAsync. Then Raise the event with the syntax given in the documentation.
// Create mock.
var mockClass = Mock.Create<MyClass>(Behavior.Strict);
// Register event handler.
mockClass.MyEventAsync += OnMyEventAsync;
// Raise event on mock.
Mock.Raise(() => mockClass.MyEventAsync += null, EventArgs.Empty);
But I receive the following error:
Telerik.JustMock.Core.MockException : Event signature System.Threading.Tasks.Task OnMyEventAsync(System.EventArgs) is incompatible with argument types (Castle.Proxies.ExternalMockMixinProxy, System.EventArgs)
I've probably missed something very obvious here. I know the above syntax should work with an event of type EventHandler<EventArgs>, but I'm not sure how to modify it to work with event of type Func<EventArgs, Task>. If anyone could clear up my confusion, I'd be most grateful. Thanks! =)
Support,
I am attempting to use JustMock to mock ServiceSecurityContext based on this article here.
If I am understanding this Telerik article, I should be able to use the NuGet package and configure a profiler using a ".runsettings" file without needing to install the configuration tool.
Here is the .runsettings file I have added to my test project:
<RunSettings>
<RunConfiguration>
<EnvironmentVariables>
<JUSTMOCK_INSTANCE>1</JUSTMOCK_INSTANCE>
<CORECLR_ENABLE_PROFILING>1</CORECLR_ENABLE_PROFILING>
<CORECLR_PROFILER>{B7ABE522-A68F-44F2-925B-81E7488E9EC0}</CORECLR_PROFILER>
<CORECLR_PROFILER_PATH>..\packages\justmock.commercial\2024.2.514.325\runtimes\win-x64\native\Telerik.CodeWeaver.Profiler.dll</CORECLR_PROFILER_PATH>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>
Unfortunately, this did not work and I am still getting the following error when running my tests.
Telerik.JustMock.Core.ElevatedMockingException: Cannot mock 'System.ServiceModel.ServiceSecurityContext'. The profiler must be enabled to mock, arrange or execute the specified target.
Detected active third-party profilers:
* {865fc36f-7fab-44b6-bbb7-c2baea8d9ad2} (from process environment)
Disable the profilers or link them from the JustMock configuration utility. Restart the test runner and, if necessary, Visual Studio after linking.
What am I missing to get this configured?
Thanks,
-Scott
Hello,
I am currently trying to mock a service I have set up (let's call it ObjectService). It's fairly straightforward - I'm just trying to verify the user is authenticated, and then the response will return an object. This is roughly what it looks like:
private Object _object;
public virtual async Task<Object> GetObject(string token,string url)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await client.GetStringAsync(url);
client.Dispose();
_object = JsonConvert.DeserializeObject<Object>(response);
return _object;
}
We've started seeing the above error on our build server. It seems to have appeared out of nowhere.
Has anyone seen this error before and know of a fix? Any help would be greatly appreciated. We're using JustMock_2023_1_117_1_Dev.
I have a class that overrides the ToString() method and returns part of a value thats set in the constructor of the class. When attempting to mock this class, JustMock ObjectValue calls the ToString() method before the UserInfo class constructor has run. In this case a null ref exception is thrown.
public string FullName => StringHelper.Format("User: '{0}'.", this.User.FullName);
public UserInfo(User author)
{
this.User = author
}
public override string ToString()
{
return this.FullName;
}
public ObjectValue(Tuple<Type, object> objectDesc)
{
AssemblyQualifiedName = objectDesc.Item1.AssemblyQualifiedName;
if (objectDesc.Item2 != null)
{
if (objectDesc.Item1.IsValueType)
{
StringValue = string.Format((objectDesc.Item1 == typeof(char)) ? "'{0}'" : "{0}", objectDesc.Item2);
}
else
{
StringValue = string.Format((objectDesc.Item1 == typeof(string)) ? "\"{0}\"" : "{{{0}}}", objectDesc.Item2);
}
}
else
{
StringValue = "<null>";
}
}
//Arrange
this.userInfo= Mock.Create<UserInfo>(user);
Mock.Arrange(() => this.userInfo.ToString()).Returns("FullName");
In my test I am using both MockingContainer and Mock to do Automocking and create concrete mocks respectively.
At the end of my test I want to ensure all of the functions I setup via Arrange for both the MockingContainer and mocked classes were ran.
Do I need to call .AssertAll() for each mocked object and the MockingContainer or can I simply call Mock.AssertAll() to make sure all Arranged functions were executed? See example below for both approaches.
// Establish mocks
var mockedControllerContainer = new MockingContainer<SomeController>();
var mockedClass = Mock.Create<SomeClass>();
// Establish test variables
IEnumerable<SomeDomainModel> records = new List<SomeDomainModel>();
// Arrange Mocks
mockedControllerContainer
.Arrange<Repository>(repo => repo.FetchRecordsWithName("name"))
.Returns(records);
mockedClass
.Arrange(c => c.SomeFunction())
.Returns(null);
// Assert
mockedControllerContainer.AssertAll();
mockedClass.AssertAll();
// Or can I use the example below to cover all cases?
Mock.AssertAll();
Which approach is best practice to ensure each function was called? This example only had one concrete class but other tests can have many so if I can avoid having to use .AssertAll() for each of them individutally that would be ideal.
The API documentation for Mock.AssertAll() states "Asserts all expected setups in the current context". How is this context defined?
Thank you!
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.
Hello,
I have the following code, as a test, but it is not working at all.
var timer1 = new Timer(500);
Mock.Arrange(() => new Timer(Arg.IsAny<double>())).Returns(timer1);
var sameTimer = new Timer(200);
Assert.AreEqual(timer1,sameTimer);
The use case, is that we have lots of timers in our legacy code that need mocking. They are not injected so I would like to override the constructor if possible and return a different object. Is this doable?
Thanks
Phillip Davis
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)