Hello,
I want to mock a large interface (~630 methods). The following line takes several minutes and several GBytes of memory:
Am I doing something wrong or is there another way to mock that object. I need this mock for every unit test so I need a faster way to do this.
Cheers
I want to mock a large interface (~630 methods). The following line takes several minutes and several GBytes of memory:
Dim mJob As IJobInterface = Mock.Create(Of IJobInterface)()
Am I doing something wrong or is there another way to mock that object. I need this mock for every unit test so I need a faster way to do this.
Cheers
19 Answers, 1 is accepted
0
Hello J,
I tried mocking an interface with 1000 methods, each with 11 parameters, and it took only 3 seconds for the mock to be created.
Could you share more details about that IJobInterface that takes so much time? If it's not a problem, you could just send us its source and the source of all dependencies.
Regards,
Stefan
Telerik
I tried mocking an interface with 1000 methods, each with 11 parameters, and it took only 3 seconds for the mock to be created.
public
interface
IHugeInterface
{
void
Do0(
object
x,
int
a0,
int
a1,
int
a2,
int
a3,
int
a4,
int
a5,
int
a6,
int
a7,
int
a8,
int
a9);
void
Do1(
object
x,
int
a0,
int
a1,
int
a2,
int
a3,
int
a4,
int
a5,
int
a6,
int
a7,
int
a8,
int
a9);
void
Do2(
object
x,
int
a0,
int
a1,
int
a2,
int
a3,
int
a4,
int
a5,
int
a6,
int
a7,
int
a8,
int
a9);
....
Could you share more details about that IJobInterface that takes so much time? If it's not a problem, you could just send us its source and the source of all dependencies.
Regards,
Stefan
Telerik
0

J
Top achievements
Rank 1
answered on 28 Oct 2013, 07:37 AM
Hello Stefan,
sorry I can't give you the source code but i have the interop.dll for you. IJobInterface is an Interface of a C++ COM class. Add it as a reference and import the e3 namespace.
There are a lot more interfaces inside just ignore them.
Greetings
sorry I can't give you the source code but i have the interop.dll for you. IJobInterface is an Interface of a C++ COM class. Add it as a reference and import the e3 namespace.
ftp://e3-delivery:vK5Bj7sPSLCe9yj@194.39.140.20/20131028-0e1d92da-a6ff-4448-aed5-ae212227d687/e3.Interop.dll
There are a lot more interfaces inside just ignore them.
Greetings
0
Hi J,
I referenced your interop assembly and tried the following code:
On my machine, the test passes in about 1.5 seconds. I tried both with and without the profiler enabled. Could I ask you to profile the unit test and see what takes so much time?
Regards,
Stefan
Telerik
I referenced your interop assembly and tried the following code:
[TestMethod]
public
void
TestPerformance()
{
var t = DateTime.UtcNow;
var mock = Mock.Create<IJobInterface>();
Mock.Arrange(() => mock.GetSignalCount()).Returns(123);
Assert.Equal(123, mock.GetSignalCount());
var t2 = DateTime.UtcNow - t;
}
Regards,
Stefan
Telerik
0

J
Top achievements
Rank 1
answered on 29 Oct 2013, 09:19 AM
Hi Stefan,
after some test runs I've figured out the following behaivior for your TestPerformance method:
1. Run unit test in VS08 - duration 20 seconds, almost no memory consumption
2. Debug unit test in VS08: duration 20 minutes then OutOfMemoryException
The run with the ANTS Performance profiler leads to the same result as 1. (20s, no memory consumption). But it still takes much longer than 1.5s on your machine..
Also I figured out that high memory consumption cames from the VS08 process (devenv.exe) neither VSTestHost.exe nor MSTest.exe.
I couldn't profile the high memory consumption issue if you know a way to do this please tell me. I've attached a profiler screenshot of the 20s run.
Cheers
PS: Sorry the first attachment was the wrong screenshot but it's quite the same.. 20sRun-New.png is the right one.
after some test runs I've figured out the following behaivior for your TestPerformance method:
1. Run unit test in VS08 - duration 20 seconds, almost no memory consumption
2. Debug unit test in VS08: duration 20 minutes then OutOfMemoryException
The run with the ANTS Performance profiler leads to the same result as 1. (20s, no memory consumption). But it still takes much longer than 1.5s on your machine..
Also I figured out that high memory consumption cames from the VS08 process (devenv.exe) neither VSTestHost.exe nor MSTest.exe.
I couldn't profile the high memory consumption issue if you know a way to do this please tell me. I've attached a profiler screenshot of the 20s run.
Cheers
PS: Sorry the first attachment was the wrong screenshot but it's quite the same.. 20sRun-New.png is the right one.
0
Hi J,
I was able to reproduce the 20s test run time. It appears to happen only when running in the .NET 2.0/3.5 runtime. On .NET 4.0 there is no such problem.
The good news is that it happens only for the first mock created for a given type. There was almost no difference in run time between creating one mock of IJobInterface and a hundred. In other words, the 20s performance penalty is constant, regardless of the number of unit tests run.
I'm still investigating the root cause of this issue. At this point I cannot promise that the performance of Mock.Create<T> for interfaces with a large number of members running on .NET 3.5 will be improved.
If the high memory consumption is coming from devenv itself, then a profiler will probably be of little use. Your test is probably hitting some hot path in the debugger or some VS add-in. I suggest you turn to general troubleshooting techniques to resolve this issue, as it appears to be unrelated to JustMock itself. I successfully debugged the test running on .NET 3.5 with the VS2013 debugger. So it seems that it might be a bug in VS2008.
I hope that the above helps you move forward. If there's anything else that I can help you with, don't hesitate to write us back again.
Regards,
Stefan
Telerik
0

J
Top achievements
Rank 1
answered on 29 Oct 2013, 12:46 PM
Hello Stefan,
thanks for your help. I've converted the solution to .NET 4.0 (VS2013) - the behaivior is more weird now :D
A test run fills the memory and takes about 1 minute now but at the end the debugger seem to crash. Everything in VS looks ok.. instead of CPU is doing nothing and the memory usage is cleared again from this point and I have to stop the test run manually.
Performance Profiler run leads to the same result as before but it runs now about 1 minute
I'm completely confused now..
Best Regards
thanks for your help. I've converted the solution to .NET 4.0 (VS2013) - the behaivior is more weird now :D
A test run fills the memory and takes about 1 minute now but at the end the debugger seem to crash. Everything in VS looks ok.. instead of CPU is doing nothing and the memory usage is cleared again from this point and I have to stop the test run manually.
Performance Profiler run leads to the same result as before but it runs now about 1 minute
I'm completely confused now..
Best Regards
0
Hello J,
Upon further investigation it appears that the VS2013 debugger also runs out of memory, so it's not a VS version issue. Also, the difference in behavior between .NET 3.5 and .NET 4.0 was caused by the way interop types get embedded. If I run the test on .NET 4.0 without embedding the interop types, then the behavior is the same - a lot of waiting ensues. The same happens with a synthetic interface.
The main problem here is that IJobInterface doesn't have 600 members - it has 6000. It implements about 15 versions of the interface, each with about 600 members and the grand total of members to mock goes to about 6000. When I tried to mock a synthetically generated interface with 6000 members, the runtime went from a second to over a minute (compared to the same interface with 1000 members).
I will continue investigating both the debugger issue and the performance issue.
Regards,
Stefan
Telerik
Upon further investigation it appears that the VS2013 debugger also runs out of memory, so it's not a VS version issue. Also, the difference in behavior between .NET 3.5 and .NET 4.0 was caused by the way interop types get embedded. If I run the test on .NET 4.0 without embedding the interop types, then the behavior is the same - a lot of waiting ensues. The same happens with a synthetic interface.
The main problem here is that IJobInterface doesn't have 600 members - it has 6000. It implements about 15 versions of the interface, each with about 600 members and the grand total of members to mock goes to about 6000. When I tried to mock a synthetically generated interface with 6000 members, the runtime went from a second to over a minute (compared to the same interface with 1000 members).
I will continue investigating both the debugger issue and the performance issue.
Regards,
Stefan
Telerik
0

J
Top achievements
Rank 1
answered on 29 Oct 2013, 03:36 PM
Hello Stefan,
ok didn't know that all methods are implemented while mocking this object. It would actually be enough if only the newest version of a method is implemented here at least in this case...
Meanwhile I tried some other mocking frameworks - the job object is always the problem except for RhinoMocks.
With the DynamicMockWithRemoting class IJobInterface is mocked in no time. Although I have to ask myself what this mock actually doesn't have compared to the others.
Greetings
ok didn't know that all methods are implemented while mocking this object. It would actually be enough if only the newest version of a method is implemented here at least in this case...
Meanwhile I tried some other mocking frameworks - the job object is always the problem except for RhinoMocks.
With the DynamicMockWithRemoting class IJobInterface is mocked in no time. Although I have to ask myself what this mock actually doesn't have compared to the others.
Greetings
0
Hello J,
Thank you for your help.
Unfortunately, we will require some additional time in order to investigate the issue. We will notify you as soon as we can provide further information.
Thank you for the understanding.
Regards,
Kaloyan
Telerik
Thank you for your help.
Unfortunately, we will require some additional time in order to investigate the issue. We will notify you as soon as we can provide further information.
Thank you for the understanding.
Regards,
Kaloyan
Telerik
0
Hello J,
In the next JustMock release (due this week) you will be able to filter which methods should be intercepted. Here's a sample how to do it:
In the above code I specified that I only want to intercept methods that are declared by the IJobInterface itself, and not by any of the old version interfaces that it inherits from. The above code drastically reduces the time to create the mock type as well as the memory usage in the VS debugger when stepping over.
I sincerely hope that this helps your scenario.
Regards,
Stefan
Telerik
In the next JustMock release (due this week) you will be able to filter which methods should be intercepted. Here's a sample how to do it:
var mock = Mock.Create<e3.IJobInterface>(conf => {
conf.SetInterceptorFilter(mi => mi.DeclaringType ==
typeof
(e3.IJobInterface));
});
I sincerely hope that this helps your scenario.
Regards,
Stefan
Telerik
0

J
Top achievements
Rank 1
answered on 04 Nov 2013, 10:31 AM
Hi Stefan,
ok sounds good. I will test it.
Best regards
ok sounds good. I will test it.
Best regards
0

J
Top achievements
Rank 1
answered on 13 Nov 2013, 11:28 AM
Hello Stefan,
is it already released? Where can I find it?
Regards
is it already released? Where can I find it?
Regards
0
Hi J,
Todor
Telerik
During the QA stage we discovered a blocking bug and we had to postpone the release. The good news is that the fix is verified and we are releasing next Monday.
Todor
Telerik
0

J
Top achievements
Rank 1
answered on 21 Nov 2013, 07:08 AM
Hello
I could test it now but still get an exception:
I tried the line Stefan mentioned...
..and converted it to VB:
Is that correct?
Cheers
I could test it now but still get an exception:
Test method JustMockTestProject.JustMockTestClass.GetFlagnoteIdsWithJustMock threw exception: System.ArgumentException: Do not supply contructor arguments when mocking an interface or delegate..
at Telerik.JustMock.Core.MocksRepository.Create(Type type, MockCreationSettings settings)
at Telerik.JustMock.MockBuilder.Create(MocksRepository repository, Type type, Object[] constructorArgs, Nullable`1 behavior, Type[] additionalMockedInterfaces, Nullable`1 mockConstructorCall, IEnumerable`1 additionalProxyTypeAttributes, List`1 supplementaryBehaviors, List`1 fallbackBehaviors, List`1 mixins, Expression`1 interceptorFilter)
at Telerik.JustMock.Mock.<>c__DisplayClass69`1.<
Create
>b__68()
at Telerik.JustMock.Core.ProfilerInterceptor.GuardInternal[T](Func`1 guardedAction)
at Telerik.JustMock.Mock.Create[T](Object[] args)
at JustMockTestProject.JustMockTestClass.GetFlagnoteIdsWithJustMock() in JustMockTestClass.vb:line 56
I tried the line Stefan mentioned...
var mock = Mock.Create<e3.IJobInterface>(conf => {
conf.SetInterceptorFilter(mi => mi.DeclaringType ==
typeof
(e3.IJobInterface));
});
..and converted it to VB:
mJob = Mock.Create(Of IJobInterface)(Function(conf) conf.SetInterceptorFilter(Function(mi) mi.DeclaringType Is GetType(e3.IJobInterface)))
Is that correct?
Cheers
0
Hello J,
The VB syntax should use Sub instead of Function. Like this:
Please, let me know if this solves the issue.
Regards,
Kaloyan
Telerik
The VB syntax should use Sub instead of Function. Like this:
mJob = Mock.Create(Of IJobInterface)(
Sub
(conf) conf.SetInterceptorFilter(
Function
(mi) mi.DeclaringType
Is
GetType
(e3.IJobInterface)))
Please, let me know if this solves the issue.
Regards,
Kaloyan
Telerik
0

J
Top achievements
Rank 1
answered on 21 Nov 2013, 09:16 AM
Hello Kaloyan,
unfortunately it doesn't. .NET 3.5 VB syntax does not allow 'Subs' in lambda expressions...
Best regards
Best regards
0
Accepted
Hello J,
I just tried the following test inside a .NET 3.5 VB test project, referring the e3 assembly:
It compiled and passed inside Visual Studio 2012.
I assume the compiler of VS2008 does not allow the Sub usage inside .NET 3.5 VB lambda expressions. Can you please check if this is passing on your side in VS2010 or later?
Thanks.
Regards,
Kaloyan
Telerik
I just tried the following test inside a .NET 3.5 VB test project, referring the e3 assembly:
<TestMethod()>
Public
Sub
TestMethod1()
Dim
mJob = Mock.Create(Of IJobInterface)(
Sub
(conf) conf.SetInterceptorFilter(
Function
(mi) mi.DeclaringType
Is
GetType
(e3.IJobInterface)))
End
Sub
I assume the compiler of VS2008 does not allow the Sub usage inside .NET 3.5 VB lambda expressions. Can you please check if this is passing on your side in VS2010 or later?
Thanks.
Regards,
Kaloyan
Telerik
0

J
Top achievements
Rank 1
answered on 06 Feb 2014, 03:27 PM
Hello Kaloyan,
i've finally managed to test it :D
It works with VS2013 (.NET 4.0) .. still takes approximately 30 seconds in debug mode but it's much better then 20 minutes.
Thank you all for help.
Best regards.
i've finally managed to test it :D
It works with VS2013 (.NET 4.0) .. still takes approximately 30 seconds in debug mode but it's much better then 20 minutes.
Thank you all for help.
Best regards.
0
Hello J,
I'm glad that the problem is now resolved to your satisfaction. If there's anything else you need help with, don't hesitate to contact us again.
Regards,
Stefan
Telerik
I'm glad that the problem is now resolved to your satisfaction. If there's anything else you need help with, don't hesitate to contact us again.
Regards,
Stefan
Telerik