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)
Hi,
I am trying to run the unit test for my .net 6 and want to see the code coverage using "Analyse Code Coverage for all Tests" in VS2022.
it successfully run all all test cases when I "run all Tests" but when I use "Analyse Code Coverage for all Tests" to run and see the code coverage, there are some test case failed throwing ThrowElevatedMockingException as below.
Message:
Telerik.JustMock.Core.ElevatedMockingException : Cannot mock 'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[AppHub.SingleView.AmazonFireStickPromo.Models.AccountPromoToken]] GetAccountPromoTokensAsync(System.String)'. The profiler must be enabled to mock, arrange or execute the specified target.
Detected active third-party profilers:
* {324F817A-7420-4E6D-B3C1-143FBED6D855} (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.
Stack Trace:
ProfilerInterceptor.ThrowElevatedMockingException(MemberInfo member)
MocksRepository.CheckMethodInterceptorAvailable(IMatcher instanceMatcher, MethodBase method)
MocksRepository.AddArrange(IMethodMock methodMock)
MocksRepository.Arrange[TMethodMock](Object instance, MethodBase method, Object[] arguments, Func`1 methodMockFactory)
<>c__DisplayClass24_0`1.<Arrange>b__0()
ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
NonPublicExpectation.Arrange[TReturn](Object target, String memberName, Object[] args)
PromoCodeManagementServiceTests.GetAllEmailStatusesAsync_WithTokenFromAccount_ExpectedListEmailStatus() line 145
GenericAdapter`1.GetResult()
AsyncToSyncAdapter.Await(Func`1 invoke)
TestMethodCommand.RunTestMethod(TestExecutionContext context)
TestMethodCommand.Execute(TestExecutionContext context)
<>c__DisplayClass1_0.<Execute>b__0()
DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
I think run all test is successful as I use specify env.runsettings in my project file (attached file).
but the test run in "Analyse Code Coverage for all Tests" failed in some methods.
Package I used
<PackageReference Include="JustMock.Commercial" Version="2023.1.117.1" />
Can someone help me to fix this one ?
Thanks
Hello
I generate a syntax tree which I will format with Formatter.Format() from the package Microsoft.CodeAnalysis.CSharp.Workspaces 4.4.0 and .NET 6. A test exists where the formatter is used but when the JustMock profiler is enabled an InvalidProgramException is thrown. When the profiler is disabled everything works fine. It fails on Windows and on Linux.
Message:
System.InvalidProgramException : Common Language Runtime detected an invalid program.
Stack Trace:
ContextIntervalTree`2.ctor(TIntrospector& introspector)
FormattingContext.ctor(AbstractFormatEngine engine, TokenStream tokenStream)
AbstractFormatEngine.CreateFormattingContext(TokenStream tokenStream, CancellationToken cancellationToken)
AbstractFormatEngine.Format(CancellationToken cancellationToken)
CSharpSyntaxFormatting.Format(SyntaxNode node, SyntaxFormattingOptions options, IEnumerable`1 formattingRules, SyntaxToken startToken, SyntaxToken endToken, CancellationToken cancellationToken)
AbstractSyntaxFormatting.GetFormattingResult(SyntaxNode node, IEnumerable`1 spans, SyntaxFormattingOptions options, IEnumerable`1 rules, CancellationToken cancellationToken)
Formatter.GetFormattingResult(SyntaxNode node, IEnumerable`1 spans, Workspace workspace, OptionSet options, IEnumerable`1 rules, CancellationToken cancellationToken)
Formatter.Format(SyntaxNode node, IEnumerable`1 spans, Workspace workspace, OptionSet options, IEnumerable`1 rules, CancellationToken cancellationToken)
Formatter.Format(SyntaxNode node, Workspace workspace, OptionSet options, CancellationToken cancellationToken)
UnitTest1.Test1() line 23
You can reproduce this by writing an unit test for that (I used xUnit):
[Fact]
public void Test1()
{
var classText = @"using System; namespace TestNameSpace.Orders { public class Order
{
public Guid Id { get; set; }
}
}";
var syntaxTree = CSharpSyntaxTree.ParseText(classText);
var workspace = new AdhocWorkspace();
var formattedClassText = Formatter.Format(syntaxTree.GetRoot(), workspace).ToFullString();
var expected = @"using System;
namespace TestNameSpace.Orders
{
public class Order
{
public Guid Id { get; set; }
}
}";
Assert.Equal(expected, formattedClassText);
}
}
See attachments. We do not use the free edition.
dotnet --info
.NET SDK:
Version: 7.0.200
Commit: 534117727b
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19045
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\7.0.200\
Host:
Version: 7.0.3
Architecture: x64
Commit: 0a2bda10e8
.NET SDKs installed:
6.0.406 [C:\Program Files\dotnet\sdk]
7.0.200 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]
Environment variables:
Not set
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
Hi there
We are trying to move our current build agents from Windows to Linux (Ubuntu 20.04) for all our dotnet6.0 applications and trying to integrate the JustMock Profiler on this machine because we depend on it in several tests.
Therefore, we followed your integration article "JustMock Integration on Linux".
We have copied the Profiler binaries to the build agent and referencing it through the environment variable:
root@8d248b92b005:/azp/Backend# printenv | grep 'CORE\|JUST' CORECLR_PROFILER_PATH=/opt/TelerikJustMock/JustMock_2022_1_223_1_Dev/Libraries/CodeWeaver/64/libTelerik.CodeWeaver.Profiler.so CORECLR_PROFILER={B7ABE522-A68F-44F2-925B-81E7488E9EC0} JUSTMOCK_INSTANCE=1 CORECLR_ENABLE_PROFILING=1
The csproj definition for referencing the JustMock library looks (at the moment) like the following:
...
<ItemGroup>
<Reference Include="Telerik.JustMock">
<HintPath Condition="Exists('C:\Program Files (x86)\Progress\Telerik JustMock\Libraries\netcoreapp2.0\Telerik.JustMock.dll')">C:\Program Files (x86)\Progress\Telerik JustMock\Libraries\netcoreapp2.0\Telerik.JustMock.dll</HintPath>
<HintPath Condition="Exists('/opt/TelerikJustMock/JustMock_2022_1_223_1_Dev/Libraries/netcoreapp2.0/Telerik.JustMock.dll')">/opt/TelerikJustMock/JustMock_2022_1_223_1_Dev/Libraries/netcoreapp2.0/Telerik.JustMock.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
...
In the tests we are calling the following method to check for the Profiler to be enabled:
public class Test_JustMockProfiler_Enabled
{
[Fact]
public void ProfilerMustBeEnabled()
{
Mock.IsProfilerEnabled.Should().BeTrue();
}
}
Then running the tests with the 'dotnet test' command:
dotnet test /path/to/Tests.dll --no-build --no-restore -l:trx --results-directory ./TestResults/
But still we get the following error:
Error Message: Expected Mock.IsProfilerEnabled to be true, but found False.
Installed dotnet:
root@8d248b92b005:/azp/Backend# dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.402 Commit: 6862418796 Runtime Environment: OS Name: ubuntu OS Version: 20.04 OS Platform: Linux RID: ubuntu.20.04-x64 Base Path: /usr/share/dotnet/sdk/6.0.402/ global.json file: Not found Host: Version: 6.0.10 Architecture: x64 Commit: 5a400c212a .NET SDKs installed: 6.0.402 [/usr/share/dotnet/sdk] .NET runtimes installed: Microsoft.AspNetCore.App 6.0.10 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.10 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Is there anything we are missing or doing wrong?
How do we properly enable the Profile on Linux to run in 'dotnet test'?
Thanks for your help in advance, cheers.
I've run into an interesting problem with JustMock. In a nutshell, if you use the C# using declaration (as opposed to a using block), and have JustMock mocking anything in the same assembly, the runtime will throw an InvalidProgramException.
I was able to isolate it down to the narrowest possible case as a proof of point. Using NUnit as the testing framework (I haven't tried with others), and a reference to JustMock, the following code will compile successfully, but at runtime will throw an InvalidOperationException when trying to run the unit test.
[TestFixture]
public class Fixture
{
public interface ITest { }
public class TestClass : IDisposable
{
public void Dispose()
{
}
}
[Test]
public async Task Test()
{
ITest mock = Mock.Create<ITest>();
using TestClass test = new();
}
}
I've played with various permutations of the problem, and it happen on .NET 4.8 (which we are using) as well as .NET 6.0, and with the version of JustMock we are using (2020.2.616.1) as well as the latest commercial release (2022.3.912.3).
For the problem to occur, the using declaration and the mock creation need not be in the same test, or even in the same fixture, but the test with the using declaration will always fail with the exception. If the async modifier is removed from the unit test, the problem goes away.
Turning off the profiler makes the problem go away, as does turning off the Automatic Mock Repository Cleanup Enabled flag in the JustMock options.
I've attached a simple .NET 6.0 based project that demonstrates the issue.