
Yesterday, I tried to mock a property of an object to define the return value but it doesn't work. I know that I am two levels depth but can you explain me what is wrong with this code...
Public
Interface
IProcessor
Property
Connection
As
IConnection
Function
Execute()
As
Boolean
End
Interface
Public
Interface
IConnection
Function
Open()
As
Boolean
End
Interface
Public
Class
DatabaseExecutor
Implements
IProcessor
Public
Property
Connection
As
IConnection
Implements
IProcessor.Connection
Public
Function
Execute()
As
Boolean
Implements
IProcessor.Execute
If
Me
.Connection.Open
Then
Return
True
Else
Return
False
End
If
End
Function
End
Class
Imports
NUnit.Framework
Imports
Telerik.JustMock
<TestFixture()>
Public
Class
DatabaseExecutorTests
''' <summary>
''' This test fail because I try to mock the function open of the objet IConnection directly
''' from the property Connection of the object Processor.
''' </summary>
''' <remarks></remarks>
<Test()>
Public
Sub
Execute_SimpleRequest_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
executor.Connection = Mock.Create(Of IConnection)()
Mock.Arrange(
Function
() executor.Connection.Open).Returns(
True
)
Assert.AreEqual(
True
, executor.Execute)
End
Sub
''' <summary>
''' This test pass because I create the connection separatly of the Processor objet and then
''' assign it to the property Processor.
''' </summary>
''' <remarks></remarks>
<Test()>
Public
Sub
Execute_SimpleRequestViaProperty_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
Dim
connection
As
IConnection = Mock.Create(Of IConnection)()
Mock.Arrange(
Function
() connection.Open).Returns(
True
)
executor.Connection = connection
Assert.AreEqual(
True
, executor.Execute)
End
Sub
End
Class
If you want, I can send you a demo but I think this will be very easy question for you.
8 Answers, 1 is accepted
Thanks for sending the issue. In case of mocking nested property, it is an extra step to create the mock of that nested property first and then use it Mock.Arrange. For your example instead doing the following:
<TestMethod()>
Public
Sub
Execute_SimpleRequest_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
executor.Connection = Mock.Create(Of IConnection)()
Mock.Arrange(
Function
() executor.Connection.Open).Returns(
True
)
Assert.AreEqual(
True
, executor.Execute)
End
Sub
You can write the test in the following way:
<TestMethod()>
Public
Sub
Execute_SimpleRequest_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
Mock.Arrange(
Function
() executor.Connection.Open).Returns(
True
)
Assert.AreEqual(
True
, executor.Execute)
End
Sub
However, in regard to the first sample, it should work as expected where you are manually creating the mock for the nested property. I am going add that to the product log as an issue.
Thanks again for using JustMock and reporting the issue.
Kind Regards,
Ricky
the Telerik team

Can you tell me when you think this bug will be corrected.
I ask you that because the workaround of creating the property object independently for dozens of tests (could be hundreds...) is not very great especially is after creating this ton of code, you will add a fix.
Thank you
Thanks again for sending the issue. Regarding the mocking of nested property I would recommend (preferred way as well) you to arrange it in the following way (directly using the get accessor):
<TestMethod()>
Public Sub Execute_SimpleRequest_ReturnsTrue()
Dim executor As New DatabaseExecutor
Mock.Arrange(Function() executor.Connection.Open).Returns(True)
Assert.AreEqual(True, executor.Execute)
End Sub
However in the coming release (Q1), you would also be able to do this:
Dim executor As New DatabaseExecutor
executor.Connection = Mock.Create(Of IConnection)()
Mock.Arrange(Function() executor.Connection.Open).Returns(True)
But this actually makes the test more verbose and in that regard the first one could be much more elegant.
Moreover, I entered a PITS issue for it. You can further track it here:
http://www.telerik.com/support/pits.aspx#/public/justmock/4500
Kind Regards,
Ricky
the Telerik team


<TestMethod()>
Public
Sub
Execute_SimpleRequest_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
Mock.Arrange(
Function
() executor.Connection.Open).Returns(
True
)
Assert.AreEqual(
True
, executor.Execute)
End
Sub
When I do this, the method Execute throw an exception because the object Connection is at nothing. But if I create an object connection, assign it to the executor.Connection and then use this object to Arrange the return of Open, it work.
<TestMethod()>
Public
Sub
Execute_SimpleRequest_ReturnsTrue()
Dim
executor
As
New
DatabaseExecutor
Dim
connection
As
IConnectionFactory
connection = executor.Connection
Mock.Arrange(
Function
() connection.Open).Returns(
True
)
Assert.AreEqual(
True
, executor.Execute)
End
Sub
Is this because of free edition or that I don't understand what you said or that what you said is wrong?
Thank you.
Thanks again for making the post.
The following test won’t pass in the free version as DatabaseExecutor.Connection is a final property or requires profiler to intercept and as free version is based on proxy (works like Moq, Rhino, etc).
<
TestMethod
()>
Public Sub Execute_SimpleRequest_ReturnsTrue()
Dim executor As New DatabaseExecutor
Mock.Arrange(Function() executor.Connection.Open).Returns(True)
Assert.AreEqual(True, executor.Execute)
End Sub
I have attached a test project with your provided classes from previous post. Please take a look at different cases (the one which passes and the ones which fail).
Using the free version, the following test will pass:
<TestMethod()>
Public Sub Execute_SimpleRequest_ReturnsTrue()
Dim executor As New DatabaseExecutor
Dim connection = Mock.Create(Of IConnection)()
executor.Connection = connection
Mock.Arrange(Function() connection.Open).Returns(True)
Assert.AreEqual(True, executor.Execute)
End Sub
However, if you try to create the Connection object manually it will fail as like the first one since partial mocking requires profiler:
<TestMethod()>
Public Sub Execute_SimpleRequest_ReturnsTrue_ManualObject()
Dim executor As New DatabaseExecutor
Dim connection As New Connection
executor.Connection = connection
Mock.Arrange(Function() connection.Open).Returns(True)
Assert.AreEqual(True, executor.Execute)
End Sub
Finally, to make it more user friendly I am adding a task to throw proper exception in free version for mocking members that requires profiler.
You can track the status of the task at :
http://www.telerik.com/support/pits.aspx#/public/justmock/4550
Please do feel free to write back for any further questions.
Kind Regards,
Ricky
the Telerik team

I tried the demo that you provide and when I try to run each test independently, it works but if I try to run all test in one batch, the function Execute_SimpleRequest_ReturnsTrue_Nested fails. For execute theses tests, I use your trial version that have a profiler.
I change the unit test engine for Nunit and I run it with Resharper.
Do you know if the last test fails when it run on batch on your side or if it is a combination of Nunit, Resharper and JustMock.
Thank you again for your great support.
Thanks again for making the post. In regard to your trial issue, MSTest runs the tests in the following sequence:
Execute_SimpleRequest_ReturnsTrue_Nested
Execute_SimpleRequest_ReturnsTrue
Execute_SimpleRequest_ReturnsTrue_ManualObject
Therefore, all the test passes. Here, Execute_SimpleRequest_ReturnsTrue runs second therefore do not interfere with the profiler initialization.
But in other cases like running with ReSharper Test Runner or TestDriven.Net, tests run in the order as the methods are defined. Therefore, in this case the execution flow is:
Execute_SimpleRequest_ReturnsTrue
Execute_SimpleRequest_ReturnsTrue_Nested
Execute_SimpleRequest_ReturnsTrue_ManualObject
So, here in the first test Connection property gets complied(.net Framework fires OnJitCompilationStarted) through this line.
executor.Connection = connection
As a result, _ReturnsTrue_Nested fails as profiler fails to intercept it. The solution is that you pre-initialize the property to avoid this kind of ordering issues.
Therefore, I added the following method in the test class and everything worked as expected.
<TestInitialize()>
Public Sub TestInit()
Mock.Partial(Of DatabaseExecutor).For(Function(x) x.Connection)
End Sub
I am re-attaching the project with this update. Please take a look at it and also do feel free to write back for any exceptions.
Kind Regards,
Ricky
the Telerik team