Re: [nsubstitute] DoNothing for private method

2,566 views
Skip to first unread message

Xerxes Battiwalla

unread,
Dec 18, 2012, 4:08:01 PM12/18/12
to nsubs...@googlegroups.com
Do you have to fake the implementation of DoSomeLogicInternal? Is it too large and complex? 

If so, then perhaps pull it out into another class which you can test independently.
If not, then i'd recommend testing the internal logic via the public method. 

If they don't work for you, there are other ways of exposing the behaviour of DoSomeLogicInternal to allow you to fake the behaviour, but none of those (or the ones above for that matter) require NSubsitute....

-xerx


On 19 December 2012 01:53, Radoslav Čáp <oso...@racap.net> wrote:
Hello all,

I have following piece of code:

public class Class1 : IClass1
    {
        public int DoSomeLogic(bool condition)
        {
            if (condition)
            {
                return this.DoSomeLogicInternal();
            }

            return -1;
        }

        private int DoSomeLogicInternal()
        {
            throw new Exception();
        }
    }

I would like to mock DoSomeLogicInternal() not to throw Exception (not to go into database in real world).

The test is here:

[Test]
        public void DoSomeLogicPublic_FakeReturnValueWithInterface_FakeWithoutException()
        {
            var testInstance = Substitute.For<Class1>();
            testInstance.DoSomeLogic(true).Returns(99);
            
            var result = testInstance.DoSomeLogic(true);

            Assert.IsTrue(result == 99);
        }

BUT DoSomeLogic has to be public virtual. In this case everything works well.

I don't want to have this method public so I have tried friendly assembly. In this case is Exception thrown.

Is there any other way to mock this?

Thank's for any idea.

--
You received this message because you are subscribed to the Google Groups "NSubstitute" group.
To view this discussion on the web visit https://groups.google.com/d/msg/nsubstitute/-/JHm5L-drL5UJ.
To post to this group, send email to nsubs...@googlegroups.com.
To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nsubstitute?hl=en.

Radoslav Čáp

unread,
Dec 19, 2012, 3:58:08 AM12/19/12
to nsubs...@googlegroups.com
Hello Xerx,

thank you for reply.

Yes, the logic is complex.

Could you provide more information about "other ways of exposing the behaviour"?

Thank you.

Xerxes Battiwalla

unread,
Dec 19, 2012, 5:58:33 AM12/19/12
to nsubs...@googlegroups.com
Sure. Firstly, if the logic in the internal method is complex enough, i'd strongly suggest extracting another class (say LogicClass) containing only that logic and test it independently. THEN you could use something like NSub to test the interaction between Class1 and your new LogicClass

Otherwise, here are some other options. (DISCLAIMER) Some of these ideas have their particularly useful occasions, but I wouldn't lean on some of them as a first option if I at all could avoid it

* Make DoSomeInternalLogic protected virtual. In your test class, create a subclass of Class1 and override "DoSomeInternalLogic" do perform no operations. Here, protected is used to give a similar veil of privacy that you'd get from "private"
* Similar alternative to above - create a base class BaseClass which contains the implementation of DoSomeLogic(bool), and an abstract definition for DoSomeInternalLogic. Class1 would inherit from BassClass and implement DoSomeInternalLogic. In your tests, create a class which subclasses BaseClass and implement DoSomeInternalLogic with no behaviour defined.
* Create a public field Func<int> DoSomeInternalLogicFunc which has the body of the DoSomeInternalLogic routine. Then in your test, replace the public Func with a func which does nothing.
* Switch to TypeMock Isolator. I havent used it, but i'm lead to believe it allows you to write tests directly against private methods

These are the ones which come to mind. The first three are variations on the concept of creating a seam which gives you access to change the behaviour of a specific part of code. I'm sure there are other patterns i've missed. If you're interested in finding more, I (and i'm certain lots of others on this mailing list) recommend the book Working Effectively With Legacy Code by Michael Feathers.

Best of luck!

-Xerx


To view this discussion on the web visit https://groups.google.com/d/msg/nsubstitute/-/Hpkf47tdizIJ.

Radoslav Čáp

unread,
Jan 14, 2013, 9:32:28 AM1/14/13
to nsubs...@googlegroups.com
Hello Xerxes,

good ideas!

The seam with sublcass which override is suitable for us.

Thank for these tips.

R.
Reply all
Reply to author
Forward
0 new messages