How do we mock Private class and Private Static class instance ?

1 Answer 142 Views
Non-public Mocking
Chandra
Top achievements
Rank 1
Chandra asked on 04 Oct 2021, 10:07 AM | edited on 04 Oct 2021, 10:07 AM

 public class Sum
    {
        public int GetSum()
        {
            return SumBy2.Add1(10,5);
        }


        public int GetSum2()
        {
            SumBy1 by1 = new SumBy1();
            return by1.Add(10, 5);
        }


        private class SumBy1
        {
            public int Add(int a, int b)
            {
                return a + b;
            }
        }

        private static class SumBy2
        {
            public static int Add1(int a, int b)
            {
                return a + b;
            }
        }
    }

 

Need to create Unit tests for Sum class.

1 Answer, 1 is accepted

Sort by
0
Ivo
Telerik team
answered on 05 Oct 2021, 11:13 AM

Hello Chandra,

With little help of reflection the desired unit tests could look like this

[TestClass]
public class SumUnitTests
{
	[TestMethod]
	public void TestSum()
	{
		var expected = -1;
		var mockSumBy2Type = typeof(Sum).GetNestedType("SumBy2", BindingFlags.Instance | BindingFlags.NonPublic);
		Mock.NonPublic.Arrange<int>(mockSumBy2Type, "Add1", Arg.Expr.AnyInt, Arg.Expr.AnyInt)
			.Returns(expected)
			.MustBeCalled();

		var sut = new Sum();
		var actual = sut.GetSum();

		Mock.Assert(mockSumBy2Type);
		Assert.AreEqual(expected, actual);
	}

	[TestMethod]
	public void TestSum2()
	{
		var expected = -1;
		var mockSumBy1 = Mock.Create(typeof(Sum).GetNestedType("SumBy1", BindingFlags.Instance | BindingFlags.NonPublic));
		Mock.NonPublic.Arrange<int>(mockSumBy1, "Add", Arg.Expr.AnyInt, Arg.Expr.AnyInt)
			.IgnoreInstance() // see https://docs.telerik.com/devtools/justmock/advanced-usage/future-mocking#future-mocking
			.Returns(expected)
			.MustBeCalled();

		var sut = new Sum();
		var actual = sut.GetSum2();

		Mock.Assert(mockSumBy1);
		Assert.AreEqual(expected, actual);
	}
}

I hope the provided information helps. If you need further assistance do not hesitate to post your question.

Regards,
Ivo
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Chandra
Top achievements
Rank 1
commented on 05 Oct 2021, 05:12 PM

Thanks Ivo for clarification. I have one more query.

if we want to write Unit Test for Private class SumBy1, how do we create it.

Ivo
Telerik team
commented on 06 Oct 2021, 01:19 PM

I have slightly touched the tests and now they are using private types directly, here they are:
[TestMethod]
public void TestPrivateSumBy2()
{
	var expected = -1;
	var sumBy2Type = typeof(Sum).GetNestedType("SumBy2", BindingFlags.Instance | BindingFlags.NonPublic);
	Mock.NonPublic.Arrange<int>(sumBy2Type, "Add1", Arg.Expr.AnyInt, Arg.Expr.AnyInt)
		.Returns(expected)
		.MustBeCalled();

	var sutTypeAccesor = PrivateAccessor.ForType(sumBy2Type);
	var actual = sutTypeAccesor.CallMethod("Add1", 10, 10);

	Mock.Assert(sumBy2Type);
	Assert.AreEqual(expected, actual);
}

[TestMethod]
public void TestPrivateSumBy1()
{
	var expected = -1;
	var sumBy1Type = typeof(Sum).GetNestedType("SumBy1", BindingFlags.Instance | BindingFlags.NonPublic);
	var mockSumBy1 = Mock.Create(sumBy1Type);
	Mock.NonPublic.Arrange<int>(mockSumBy1, "Add", Arg.Expr.AnyInt, Arg.Expr.AnyInt)
		.IgnoreInstance()
		.Returns(expected)
		.MustBeCalled();

	var sut = Activator.CreateInstance(sumBy1Type);
	var sutAccesor = new PrivateAccessor(sut);
	var actual = sutAccesor.CallMethod("Add", 10, 10);

	Mock.Assert(mockSumBy1);
	Assert.AreEqual(expected, actual);
}
Chandra
Top achievements
Rank 1
commented on 07 Oct 2021, 10:09 AM

Thanks Ivo for your answers. Appreciate your help.
Ivo
Telerik team
commented on 07 Oct 2021, 01:28 PM

It was a pleasure for me to help you. Wish you a great day!
Tags
Non-public Mocking
Asked by
Chandra
Top achievements
Rank 1
Answers by
Ivo
Telerik team
Share this question
or