With R3 2023 (2023.3.1011.155) JustMock introduces a new functionality that might lead to a huge performance drop and event to unexpected failures. Currently, the issue could be suppressed by setting up an environment variable JUSTMOCK_NEWOBJ_INTERCEPTION_ON_OVERWRITE_ENABLED to 0 (the default value is 1), but a more reliable and independent solution should be found.
if you use the C# using declaration and have JustMock advanced (elevated) mode enabled, the runtime will throw an InvalidProgramException.
Find below the sample code that demonstrates the issue:
public class TestClass : IDisposable
{
public void Dispose()
{
}
}
[TestClass]
public class Fixture
{
public interface ITest { }
[TestMethod]
public async Task Test()
{
ITest mock = Mock.Create<ITest>();
using TestClass test = new();
}
}
The issue is about interoperability between JustMock and AutoFixture. The unit test run can be 90% faster if all the fixtures are created before the JustMock arrangements.
Here is a sample code that figures out the issue:
[Fact]
public void Slow
{
var fixture = new Fixture():
var items1 = fixture.Create<List<Item>>();
Nock.Arrange(() => ItemsRepository.GetItems1()).Returns(items1);
var items2 = fixture.Create<List<Item>>();
Nock.Arrange(() => ItemsRepository.GetItems2()).Returns(items2);
var items3 = fixture.Create<List<Item>>();
Nock.Arrange(() => ItemsRepository.GetItems3()).Returns(items3);
var items4 = fixture.Create<List<Item>>();
Nock.Arrange(() => ItemsRepository.GetItems4()).Returns(items4);
}
[Fact]
public void Fast()
{
var fixture = new Fixture():
var items1 = fixture.Create<List<Item>>();
var items2 = fixture.Create<List<Item>>();
var items3 = fixture.Create<List<Item>>();
var items4 = fixture.Create<List<Item>>();
Nock.Arrange(() => ItemsRepository.GetItems1()).Returns(items1);
Nock.Arrange(() => ItemsRepository.GetItems2()).Returns(items2);
Nock.Arrange(() => ItemsRepository.GetItems3()).Returns(items3);
Nock.Arrange(() => ItemsRepository.GetItems4()).Returns(items4);
}
The test duration should not be dependent on the exact implementation.
There are no ReturnsAsync methods for mocking container async methods.
There should be a set of methods to mock async methods of a container similar to regular object mocking.
As a user I should be able to write code like:
container.Arrange<IContainer>(r => r.SomeAsyncMethod("data")).ReturnsAsync("returnValue");
Considering the sample class
using Azure.Messaging.ServiceBus;
public class Class2
{
private static ServiceBusSender messageToTopicSender;
private static string topicName;
public static void SetRequestTopicClient(string serviceBusConnectionString, string topName)
{
topicName = topName;
ServiceBusClient serviceBusClient = new ServiceBusClient(serviceBusConnectionString);
messageToTopicSender = serviceBusClient.CreateSender(topicName);
}
}
and the following tests
[TestClass]
public class Class1Test
{
[TestInitialize]
public void SetUp()
{
Mock.Arrange(() => Class2.SetRequestTopicClient("", "")).DoNothing();
}
[TestMethod]
public void TestA()
{
Class2.SetRequestTopicClient("", "");
}
}
[TestClass]
public class Class2Test
{
static ServiceBusClient serviceBusClient = Mock.Create<ServiceBusClient>();
ServiceBusSender messageToTopicSender = Mock.Create<ServiceBusSender>();
[TestInitialize]
public void SetUp()
{
Mock.Arrange(() => new ServiceBusClient("conStr")).Returns(serviceBusClient);
Mock.Arrange(() => serviceBusClient.CreateSender("myTopic")).Returns(messageToTopicSender);
}
[TestMethod]
public void TestB()
{
Class2.SetRequestTopicClient("conStr", "myTopic");
}
}
Executing the tests in order TestA -> TestB results in failed TestB, but changing the order or runining them standalone succeeds.The outcome of the tests should not be dependent of the execution order.
A unit test run against a simple class using EntityFramework never completes, here's the code:
public class DbContext1 : DbContext
{
public DbContext1(string connectionString)
{
}
}
public class Program
{
private static readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
public async Task Run()
{
await _lock.WaitAsync();
try
{
await InsertDbRow();
}
finally
{
_lock.Release();
}
}
private static async Task InsertDbRow()
{
await RetryWrapperAsync(async () =>
{
using DbContext1 dbContext = new DbContext1("con str");
await dbContext.SaveChangesAsync();
});
}
public static async Task RetryWrapperAsync(Func<Task> operation)
{
for (int i = 0; i < 3; i++)
{
try
{
await operation();
break;
}
catch (Exception)
{
await Task.Delay(100);
}
};
}
}
[TestClass]
public class ProgramTest
{
private readonly DbContext1 mockContext1 = Mock.Create<DbContext1>();
[TestInitialize]
public void SetUp()
{
Mock.Arrange(() => new DbContext1("con str")).Returns(mockContext1);
}
[TestMethod]
public async Task TestMethod()
{
// Arrange
Program program = new Program();
// Act
await program.Run(); // <-- at this point the test hangs
}
}
Adding do-nothing arrangement on mockContext.SaveChanges fixes the hang, but the expectation is that mock will handle this case by default and there is no need to be explicitly arranged.
Provide support for .NET MAUI projects.
Let me explain in details the current situation:
I have Unit Test project using JustMock and running into a problem. It seems like JustMock is using the wrong version number to locate the SDK. let me explain:
The project is set to: <TargetFramework>net7.0</TargetFramework>
But it also has <UseMaui>true</UseMaui> enabled
I am getting the following error:
"Framework: 'Microsoft.Maui.Core', version '7.0.92' (x64) .NET location: C:\Program Files\dotnet No frameworks were found.
That 7.0.92 version is only for the MAUI workload version, not the SDK versions. It seems JustMock uses a workload version as a SDK version.
Allow the developer to create custom behaviors and use them in an arrangement. Something like the following:
Mock.Arrange(() => foo.CalcData(Arg.AnyInt, Arg.AnyInt), new IBehavior[]
{
new LogInvocation(),
new ReturnBaseOrDefaultValue(),
});
Hi.
i saw this: https://www.telerik.com/forums/how-can-i-mock-multiple-instances-of-a-struct
but still dont understand why JustMock works that way in the first place. why does it union struct mocks by value?
the above solution is only possible when i mock a struct i can change (and then add the id to it) but what about struct's from the framework that i cannot control? Is there a way to tell JustMock not to union mock structs?
Thanks,
Yosi
Dear Telerik team,
It is nice to have a way to generate mocks.
But it is annoying to have lots of those messages for references in XML comments. I had to turn the feature off. Which might be the case for other customers too.
Maybe you want to have a look into it.
We're developing .net 5/core services, using Rider IDE and MacOS.
Please:
1. Add support to run JustMock under MacOS (profiler need to be supported, enabled issue, etc.), or if already supported, please provide instructions of how to activate it per test, for example using NUnit.
2. Add integration with Rider so all the process will be much easier.
I am unable to mock interfaces that contain a method with an `in` parameter. When running the following code snippet, the result is an exception:
Message:
Test method Example.UnitTests.UnitTest.TestMethod threw exception:
Telerik.JustMock.Core.MockException: Abstract type 'Example.UnitTests.InParamExample' is not accessible for inheritance.
Stack Trace:
MocksRepository.Create(Type type, MockCreationSettings settings)
<>c__38`1.<Create>b__38_0()
ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
UnitTest.TestMethod() line 23
namespace Example.UnitTests
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Telerik.JustMock;
public interface ParamExample
{
void Foo(int param);
}
public interface InParamExample
{
void Foo(in int param);
}
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestMethod()
{
var mockedParamExample = Mock.Create<ParamExample>();
var mockedInParamExample = Mock.Create<InParamExample>();
}
}
}
Mock.Create<IPool>() fails with
Telerik.JustMock.Core.MockException : Abstract type 'IPool' is not accessible for inheritance.
In Telerik.JustMock.Core.MocksRepository.Create(Type type, MockCreationSettings settings)
In Telerik.JustMock.Mock.<>c__39`1.<Create>b__39_0()
In Telerik.JustMock.Core.ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
when trying to create a mock object from
public interface IPool
{
object GetItem(in Struct a, out Class b);
}