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);
}
The case is reproducible (but might not be limited to) in a dedicated environment including Windows 10, JustMock R3.2021, Visual Studio 2019 and .NET 5. When the profiler is enabled the Visual Studio has problems with the test discovery and reports "Stack overflow" exception. The same applies to building solutions with Azure Function project.
CLR Stack from memory dump captured upon test execution:
000000CD7CE038D0 00007ffafb22d3b6 [GCFrame: 000000cd7ce038d0] 000000CD7CE03A40 00007ffafb22d3b6 [GCFrame: 000000cd7ce03a40] 000000CD7CE0A530 00007ffafb22d3b6 [PrestubMethodFrame: 000000cd7ce0a530] System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(System.Reflection.RuntimeAssembly, System.String) 000000CD7CE0A988 00007ffafb22d3b6 [GCFrame: 000000cd7ce0a988] 000000CD7CE0E3C0 00007ffafb22d3b6 [PrestubMethodFrame: 000000cd7ce0e3c0] System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(System.Reflection.RuntimeAssembly, System.String) ... (omitted for brevity) 000000CD7CF72548 00007ffafb22d3b6 [GCFrame: 000000cd7cf72548] 000000CD7CF75F80 00007ffafb22d3b6 [PrestubMethodFrame: 000000cd7cf75f80] System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(System.Reflection.RuntimeAssembly, System.String) 000000CD7CF763D8 00007ffafb22d3b6 [GCFrame: 000000cd7cf763d8] 000000CD7CF79E10 00007ffafb22d3b6 [PrestubMethodFrame: 000000cd7cf79e10] System.Runtime.Loader.AssemblyLoadContext.OnAssemblyResolve(System.Reflection.RuntimeAssembly, System.String) 000000CD7CF7A268 00007ffafb22d3b6 [GCFrame: 000000cd7cf7a268] 000000CD7CF7DCA0 00007ffafb22d3b6 [PrestubMethodFrame: 000000cd7cf7dca0] System.Collections.Generic.Dictionary`2[[System.__Canon, System.Private.CoreLib],[System.__Canon, System.Private.CoreLib]]..ctor() 000000CD7CF7DF10 00007FFA9B787B2A System.AppContext..cctor() [/_/src/System.Private.CoreLib/shared/System/AppContext.cs @ 16] 000000CD7CF7E340 00007ffafb2b6c93 [GCFrame: 000000cd7cf7e340] 000000CD7CF7ED18 00007ffafb2b6c93 [HelperMethodFrame: 000000cd7cf7ed18] 000000CD7CF7EE20 00007FFA9B7876B9 System.AppContext.Setup(Char**, Char**, Int32)
Referencing the nuget Microsoft.ApplicationInsights.AspNetCore V2.20.0 in the project that is tested leads to the VS 2019 code coverage failing to produce the report. Here are the steps to reproduce:
1. Create a project from the template ASP.NET Core Web API targeting .NET 5
2. Add a reference to the nuget package Microsoft.ApplicationInsights.AspNetCore V2.20.0
3. Create a unit test project from the C# JustMock Test Project (.NET Core) template.
4. Run the VS code coverage.
Expected result: the code coverage report is produced.
Actual result: there is no code coverage report
The threading model of UI apps differs from the test host and this might become a source of issues like the following: System.InvalidOperationException: "The calling thread must be STA, because many UI components require this". The request is about extending JustMock with some helpers that can be used to solve this issue easily.
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.
Considering the following simple test scenario:
public abstract class TestBase
{
public static TestContext TestContext { get; set; }
}
[TestClass]
public class UnitTest1 : TestBase
{
[ClassInitialize]
public static void ClassInitlialize(TestContext ctx)
{
TestContext = ctx;
}
[TestMethod]
public void TestMethod1()
{
}
}
[TestClass]
public class UnitTest2 : TestBase
{
[ClassInitialize]
public static void ClassInitlialize(TestContext ctx)
{
TestContext = ctx;
}
[TestMethod]
public void TestMethod1()
{
}
}
Attempt to run the tests above with JustMock profiler enabled fails with System.InvalidProgramException. The issue is not reproducible with MSTest.TestFramework and MSTest.TestAdapter packages prior to 3.0.x.
JustMock interprets anonymous types as tuples. The sample below demonstrates the issue:
public interface IAnsweringService
{
(int code, string desc) GetAnswer(string question);
}
[TestMethod]
public void AnswerToTheUniverseQuestionTest()
{
var apiMock = Mock.Create<IAnsweringService>();
var expectedAnswer = new { code = 42, desc = "Answer to the Ultimate Question of Life" };
Mock.Arrange(() => apiMock.GetAnswer(Arg.AnyString)).Returns(expectedAnswer);
var actualAnswer = apiMock.GetAnswer("What is a universe question answer?");
Assert.AreEqual(expectedAnswer.code, actualAnswer.code);
Assert.AreEqual(expectedAnswer.desc, actualAnswer.desc);
}
Telerik.JustMock.Core.MockException: The chained return value type '<>f__AnonymousType1`2[System.Int32,System.String]' is not compatible with the arranged method's return type 'System.ValueTuple`2[System.Int32,System.String]'
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
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");
To replicate the problem using the provided project, follow these steps:
1. Open the solution in Rider.
2. Set breakpoints at the beginning of the test.
3. Start debugging the test.
4. Step into the constructor of the Car class and inspect the contents of the array. Note that if this step is skipped, the issue will not be reproducible.
5. Step out of the constructor.
6. Continue execution until just before calling the virtual function for the Number property.
7. Step into the function.
**EXPECTED** The value of Name should be visible.
**ACTUAL** A debugger error occurs.
The issue can appear in both Visual Studio (showing "Internal error in the C# compiler") and Rider (showing "Read out of bounds").
As a developer, I want to be able to automock classes that have concrete classes injected
If I have a constructor like this: public Foo(IAccount fromAccount, IAccount toAccount) { //code }, I need to be able to distinguish between the two accounts when automocking. container.Arrange<IAccount>() won't work. Perhaps container.Arrange<IAccount>[0] would.
Currently, I can only assert all when automocking. It would be nice to be able to assert individually. container.Assert<IAccount>(). If we implement my other item (http://feedback.telerik.com/Project/105/Feedback/Details/850-distinguish-between-automocked-items-when-multiple-of-the-same-are-in-the-constru) then it would be container.Assert<IAccount>[0] if there were more than one IAccount in the constructor.
Current behavior: Mock.Arrange(xxx).IgnoreInstance(); //mock all future instances of the type on which I set an expectation. Feature Request: Mock.Arrange(xxx).IgnoreInstance().Next(); //mock the next instance of the type on which I set an expectation. ...and even better... Mock.Arrange(xxx).IgnoreInstance().Skip(3).Next(); //mock the 4th instance of a type on which I set an expectation.
When I try to invoke method from intercepted class in multi-thread test sometimes I get following exception: System.ArgumentException Destination array was not long enough. Check destIndex and length, and the array's lower bounds. at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable) at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length) at System.Collections.Generic.List`1.CopyTo(T[] array, Int32 arrayIndex) at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList(IEnumerable`1 source) at Telerik.JustMock.Weaver.ContainerContext.InstanceIdentifier.GetUniqueId(Object target) at Telerik.JustMock.Weaver.ContainerContext.Get(Type targetType, MethodBase methodInfo, Object target) at Telerik.JustMock.Weaver.ContainerContext.Get(MethodBase methodBase, Object target) at Telerik.JustMock.Weaver.Interceptors.WeaverInterceptor.OnInvocation(IInvocation invocation) at Telerik.JustMock.Weaver.Interceptors.WeaverInterceptor.Telerik.JustMock.Weaver.Interceptors.Abstraction.IWeaverInterceptor.Intercept(IInvocation invocation) at TestClass_Interceptor_620e5e80fe0c4d738f7ef291ea50ea2a.Intercept(TestClass, ref Boolean) at ExceptionExample.TestClass.ExecuteSomething() in Test.cs: line 174 at ExceptionExample.RunMethod() in Test.cs: line 199 at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() Sample class that generates exception: [TestFixture] public class ExceptionExample { static ExceptionExample() { Mock.Initialize<TestClass>(); } public class TestClass { public void ExecuteSomething() { int y = 0; for (int i = 0; i < 100; i++) y += i; } } [Test] public void MethodName() { List<Thread> l = new List<Thread>(); for (int i = 0; i < 6; i++) { Thread t = new Thread(RunMethod); t.Start(); l.Add(t); } l.ForEach(th => th.Join()); } private void RunMethod() { for (int i = 0; i < 10000; i++) { TestClass tc1 = new TestClass(); tc1.ExecuteSomething(); } } }