My team and I have spotted some odd behaviour with the latest version of JustMock (2015.3.929.5) when targeting a Windows Store app. If we create a mock for an object in a helper method, the mock fails when making assertions for calls to the mock. The following code illustrates the issue: [TestMethod] public void ThisWillFail() { var subject = CreateSubject(); subject.DoSomething(); subject.Assert(s => s.DoSomething(), Occurs.Once()); } [TestMethod] public void ThisWillPass() { var subject = Mock.Create<ISubject>(); subject.DoSomething(); subject.Assert(s => s.DoSomething(), Occurs.Once()); } public interface ISubject { void DoSomething(); } private static ISubject CreateSubject() { return Mock.Create<ISubject>(); } In this code, the first test will fail but the second test will pass. The only difference is that, in the first test, we're setting up the mock in a helper method. We have a "Unit Test Library (.NET for Windows Store apps)" referencing the Telerik.JustMock assembly. I have attached a simple project containing this implementation. It's worth noting that the same code passes in a regular .NET class library; it only fails in a "Unit Test Library (.NET for Windows Store apps)". It's also worth noting that this worked under an older version of the assembly (2014.3.1021.2). Any help would be appreciated, as we currently have around 3,000 tests and a good proportion of them set up their mocks using a helper method in this way. Regards William Cowell
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.
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").
Update reference functionality wrongly suggests updating JustMock assembly reference and even more - detects currently referenced one as a lite version, see the screenshot below:
The documentation on Fluent Mocking ends with this statement:
Important
Note that when you use Fluent Asserts only arrangements marked with either MustBeCalled or Occurs will be verified. For other tests you have to use the explicit assert.
What this fails to note is that, while this is true of the function "Assert", there is another function, "AssertAll", which will flag an error if any Arranged function call was not utilized.
On a related note, I left other suggestions for this same page a day or two ago. I would have liked to leave the above statement using the same feedback utility, but I can no longer find the control that I used to leave those initial suggestions.
The issue is demonstrated with the following sample:
[Theory]
[MemberData(nameof(GetMemberDataContext))]
public void ValidParameters_Success(int param1, int param2)
{
// Arrange
Mock.SetupStatic(typeof(MyClass), Behavior.Strict, StaticConstructor.Mocked);
Mock.Arrange(() => MyClass.method1()).Returns(true);
// Act
IService service = new Service();
bool result = service.method2();
// Assert
Assert.True(result);
Mock.Assert(() => MyClass.method1(), Occurs.Once()); // <-- the test fails here because it reports that method invocation occurs twice
}
The issue in not observed if the code is modified in the following way, which indicates behavioral incinsistency:
[Theory]
[MemberData(nameof(GetMemberDataContext))]
public void ValidParameters_Success(int param1, int param2)
{
// Arrange
Mock.SetupStatic(typeof(MyClass), Behavior.Strict, StaticConstructor.Mocked);
Mock.Arrange(() => MyClass.method1()).Returns(true).OccursOnce();
// Act
IService service = new Service();
bool result = service.method2();
// Assert
Assert.True(result);
Mock.Assert<MyClass>();
}
The following code snippet causes a hang in the test execution while being debugged:
Mock.SetupStatic(typeof(TimeSpan), Behavior.CallOriginal, StaticConstructor.NonMocked);
Mock.Arrange(() => TimeSpan.FromSeconds(15)).Returns(TimeSpan.MinValue);
The issue can be temporary solved by disabling the DebugWindow via JustMock extension menu.
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.
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.