Search code examples
c#unit-testingmockingnunitmoq

Mock internal concrete methods


How I should mock below lines?

            ABCRepository abcObj = new ABCRepository();
            var model = new NamesList
            {
                ALayoutNames = abcObj.ALayout(),
                BLayoutNames = abcObj.BLayout(),
                CLayoutNames = abcObj.CLayout(),
                DLayoutNames = abcObj.DLayout(),
                ELayoutNames = abcObj.ELayout()
            };

I have mocked first line with its interface like below

Mock<IABCRepository> _iabcrepository = new Mock<IABCRepository>();

But how to proceed for NamesList object?


Solution

  • This needs a bit of refactoring. That is why I find that Unit Tests help create a better code.

    So here it goes, step by step:

    1. Move the ABCRepository in the constructor as an argument of your class i.e.
        public class ClassToTest {
            private IABCRepository abcObj;
    
            public ClassToTest(IABCRepository repo) {
                 this.abcObj = repo;
            } 
    
            public DoingSomething() {
                var model = new NamesList
                {
                    ALayoutNames = this.abcObj.ALayout(),
                    BLayoutNames = this.abcObj.BLayout(),
                    CLayoutNames = this.abcObj.CLayout(),
                    DLayoutNames = this.abcObj.DLayout(),
                    ELayoutNames = this.abcObj.ELayout()
                };
            }
        }
    
    1. In your test you need to do two things, first setup the mock responses
        Mock<IABCRepository> _iabcrepository = new Mock<IABCRepository>();
        _iabcrepository.Setup(foo => foo.ALayout()).Returns(MockValue);
        _iabcrepository.Setup(foo => foo.BLayout()).Returns(MockValue);
        // etc
    
    1. In your test (or init, or wherever you create the instance to be tested) now create the mock object and pass it through the constructor
        var classToTest = new ClassToTest(_iabcrepository.Object);
    

    Now when you call the DoSomething function, the mocked repository will return the mocked values.