I have a scenario that I cannot seem to get working just like i would like.
I have been able to successfully write a test method against my private method just fine.
Now, I'm trying to write a test against my public method. In the public method, i want to the call to the private method to be mocked and return a mocked value so the remainder code in my public method will handle that result.
However, when it comes time to execute the line of code in the public method that would call the private method, all that comes back is NULL. I don't get my mocked value.
Here is my current test
var mockedClass = Mock.Create<JHADirectoryServiceAPI>(Constructor.Mocked);
var autoFix =
new
Fixture();
var otherPhoneDtoCollection_AM = autoFix.Create<IEnumerable<OtherPhoneDto>>();
var inst =
new
PrivateAccessor(mockedClass);
Mock.NonPublic.Arrange<IEnumerable<OtherPhoneDto>>(mockedClass,
"GetOtherPhonesByOfficeID"
, Arg.AnyGuid)
.DoInstead(()=> inst.CallMethod(
"GetOtherPhonesByOfficeID"
, Arg.AnyGuid)).ReturnsCollection(otherPhoneDtoCollection_AM);
Assume the below code...
Public
IEnumerable<Object>
GetDetails(Guid value)
{
//do some local stuff
var result = GetOtherPhonesByOfficeID(value);
//eval result
return
myList
}
private
IEnumerable<OtherPhoneDto>
GetOtherPhonesByOfficeID(Guid value)
{
//Do some Stuff
return
myList
;
}
6 Answers, 1 is accepted
Figured it out. Had to use the Mock.NonPublic.Wrap function as mentioned here.
http://www.telerik.com/help/justmock/advanced-usage-mocking-non-public-members-and-types.html
ultimately, this code snippet worked.
dynamic mockedClassWrap = Mock.NonPublic.Wrap(mockedClass);
Mock.NonPublic.Arrange<
IEnumerable
<OtherPhoneDto>>(mockedClassWrap .GetOtherPhonesByOfficeID(ArgExpr.IsAny<
Guid
>())).Returns(otherPhoneDtoCollection_AM);
I am glad you've managed to resolve the issue. However I think there is something that you've missed - Mock Behaviors.
When you create a mock with Mock.Create and don't specify the behavior, its member implementation are empty stubs (because of the default behavior). Although you've arranged the private method, the public method has an empty implementation that doesn't call the original method (that calls the private method). To achieve what you want you have to create the mock with CallOriginal behavior. I prepared a small example. Consider that code
public
class
Student
{
public
string
GetName()
{
return
GetPrivateName();
}
private
string
GetPrivateName()
{
return
"Svetlozar"
;
}
}
Here is how to arrange the private method and leave the public one with the original implementation.
[TestMethod]
public
void
TestMethod1()
{
var mocked = Mock.Create<Student>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<
string
>(mocked,
"GetPrivateName"
).Returns(
"Svetlio"
);
Assert.AreEqual(
"Svetlio"
, mocked.GetName());
}
I hope that makes sense. Let us know if you have other questions.
Regards,
Svetlozar
Telerik by Progress
Is there no better why to test if a protected or a private method was called? I know it from mockito in the java work there I can check if a "package" method was called like a public method.
I do not like that I have to call for example:
Mock.NonPublic.Arrange<string>(mocked, "GetPrivateName").Returns("Svetlio");
Is there no better way that I not need to write "GetPrivateName" by myself. I like to have a way that if can find the methods in intellisense...
Thank you for the interest in JustMock.
Can you be more specific how exactly do you expect a non-public method call should look? Right now, JustMock uses expressions to access the public APIs, however this is not the case with private APIs since they are not accessible.
If you have good idea we'll be really happy to look deeper into it and estimate it.
Thanks,
Kammen
Progress Telerik
Hi Kamman
I worked the last 2 years with java. There its possible to test easy if a package-internal method was called (classes must have the same package)
See example:
Class to Test:
package [xy].web.client.application.article.detail;
[imports]
public class ArticleDetailFragment {
....
@Inject
public ArticleDetailFragment(...){
...
}
@Override
public void start() {
...
loadMasterData();
loadArticle();
}
void loadMasterData() {
...
}
void loadArticle() {
...
}
}
TestClass:
package xy.web.client.application.article.detail;
[imports]
@RunWith(MockitoJUnitRunner.class)
public class ArticleDetailFragmentTest {
private ArticleDetailFragment presenter;
@Before
public void setup() {
presenter = new ArticleDetailFragment(...);
}
@Test
public void start() {
// Arrange
presenter = spy(presenter);
// Act
presenter.start();
// Assert
verify(view).setPresenter(presenter);
verify(presenter).loadMasterData();
verify(presenter).loadArticle();
}
}
If I understand your sample correctly, in Java you can easily mock package-internal methods from tests located in the same package.
If this is the case, I'm glad to confirm that this is achievable in .NET world too. Even more, since .NET 2.0, you can mark a project as internal visible, so you can test class' internal methods from another project. For more information, I'm suggesting this article.
However, I'm not aware of a way that you can access private members outside a class other than using Reflection. And using the Mock.NonPublic, PrivateAccessor and other helper classes just does this for you.
Hope this answers your questions. If you need further information, do not hesitate to contact me.
Regards,
Kammen
Progress Telerik