chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
as usual, I am using MSTEST that call fake private method

myAccessor target = new myAccessor()

           using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                dtMax = target.InUTCTime(dtMax, 1, 1, 1);
                recorder.Return(new DateTime(1999, 10, 1, 19, 18, 02));
            }

           using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                dtMax = target.InUTCTime1(dtMax, 1, 1, 1);
                recorder.Return(new DateTime(1999, 10, 1, 19, 18, 02));
            }



In one of the test cases, both methods will be called, in another case, only 1 method will be called. I want to asset something like fake.verify.notcalled. How do I do that?
asked by ben1628 (2k points)

13 Answers

0 votes
Hi,

I recommend you to use the new AAA API, you can use it as well for avoiding usage of Accessors:
// Arrange
var objectUnderTest = Isolate.Fake.Instance<ObjectUnderTest>(Members.CallOriginal);

Isolate.NonPublic.WhenCalled(objectUnderTest, "InUTCTime")
    .WillReturn(new DateTime(1999, 10, 1, 19, 18, 02));

Isolate.NonPublic.WhenCalled(objectUnderTest, "InUTCTime1")
    .WillReturn(new DateTime(1999, 10, 1, 19, 18, 02));

// Act
// Some logic here that needs to be tested

// Assert
Isolate.Verify.NonPublic.WasNotCalled(objectUnderTest, "InUTCTime1");


This way you can achieve better readability of the test with simpler code.

By the way, in this specific case where verifying a method was not called there is no need to set behavior for it using WhenCalled.

Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
0 votes
Part of the reasons of using accessor is it allows me to test the private method. In my case, I have something like this

MyAccessor target = new myAccessor();
target.callPrivateMethod(....)

and then I can debug and step throught callPrivateMethod. How do I do something like this in your example without accessor?

BTW, if I have a private dictionary inside that target class, I was able to do
target.somedictionary.add(...)

with your method, I supposed I can do
var nameInTest = new Dictionary<...>();

Isolate.NonPublic.Property.WhenGetCalled(fake, "nameInTarget").WillReturn(nameInTest);
but it doesn't seem to work
answered by ben1628 (2k points)
0 votes
Hi,

Can you post please the code under test?

Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
0 votes
well, I think I can use isolate.invoke.method to call private method. But how about in the case of out parameter?

I also have problem with private dictionary. It complains it doesn't have a get

public myClass
{
        private Dictionary<int> dict = new Dictionary<int>();

}



TestClass
{
            var myDict= new Dictionary<int>();

            myDict.Add(1, 1);
            
            Isolate.NonPublic.Property.WhenGetCalled(fake, "dict").WillReturn(myDict);
}
answered by ben1628 (2k points)
0 votes
furhter to the previous post, this is another problem I have

No overloads of method "privateMethod" receive argument types {Int32, int, int, int, Boolean, Boolean}
Possible candidates are:
   - privateMethod(Int32, int, int, int, Boolean, Boolean&)


the method has
privateMethod(int32, int, int, int, Boolean, Out Boolean)

I invoke the method using this
boolean Need2CheckMax = true;
Isolate.Invoke.Method(class2Test, "privateMthod", 1, 1,1,1, ture, (object) Need2CheckMax);
answered by ben1628 (2k points)
0 votes
Hi,

Private invoke feature does not support at the moment methods with ref/out parameters. As I can see from your test it can be useful and I added it to the features requests in Isolator.

In general, too much access to private members may cause too fragile tests. If you'd like, you can describe what you're trying to test and more code and I'll help writing a test based on public state if possible.

Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
0 votes
Thanks.

How about private dictionary? are you able to show me an exampleZ that works?
answered by ben1628 (2k points)
0 votes
Hi,

There is some difference between faking properties to fields.

In the example posted the dictionary is a field, therefor it has no set/get accessors. Isolator has a solution for this case to. You can use ObjectState to get an manipulate private fields.

For example:
public class myClass
{
    private List<int> list = new List<int>();
}

[TestMethod]
public void SetPrivateFieldExample()
{
    var myClass = new myClass();

    var fakeList = new List<int>(){1};
    ObjectState.SetField(myClass, "list", fakeList);
}


Best Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
0 votes
>>too much access to private members may cause too fragile tests<<

In serveral instances, you make remark about acessing private member produce fragile test. IMHO, unit test is about white box testing and accessing and testing private members/functions is a must.

Are you able to make typemock similiar to MS accessor so we can test out/ref parameter and have intellisense. On the other hand, that may not be important, I can live with the using nonpublic call, but without out/ref support, typemock is not of great use to our company.

When do u think you will have such feature available? I will evaulate it again when that happen.
answered by ben1628 (2k points)
0 votes
Hi Ben,

Actually there is much sense in the suggestions not to mess too much with private methods during tests.
While unit testing definitely fall under the category of white box testing, you still want to focus on testing behavior of your classes (public API) and not on your internal structure (private methods). Doing so will decrease the maintenance cost of your test when changing internal structure, which in OO is allowed to change quite frequently.

Heres a nice post on the problem of overspecified tests.
answered by error (6.6k points)
...