Using the PrivateObject
class I can access private members of a class.
But I cannot access private members if that class is mocked using Moq.
Example Code
<code>using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Xunit;
using Assert = Xunit.Assert;
namespace MyNamespace;
public class Temp
{
private int I { get; set; }
public int PublicI
{
get => I;
set => I = value;
}
public Temp(int i)
{
I = i;
}
}
public class Testing
{
[Fact]
[Trait("Category", "Unit")]
public void TestNormal()
{
var temp = new Temp(7);
Assert.Equal(7, temp.PublicI);
temp.PublicI = 8;
Assert.Equal(8, temp.PublicI);
var po = new PrivateObject(temp);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
[Fact]
[Trait("Category", "Unit")]
public void TestMocked()
{
var mock = new Mock<Temp>(7);
Assert.Equal(7, mock.Object.PublicI);
mock.Object.PublicI = 8;
Assert.Equal(8, mock.Object.PublicI);
var po = new PrivateObject(mock.Object);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
// Following line throws System.MissingMethodException
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
}
</code>
<code>using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Xunit;
using Assert = Xunit.Assert;
namespace MyNamespace;
public class Temp
{
private int I { get; set; }
public int PublicI
{
get => I;
set => I = value;
}
public Temp(int i)
{
I = i;
}
}
public class Testing
{
[Fact]
[Trait("Category", "Unit")]
public void TestNormal()
{
var temp = new Temp(7);
Assert.Equal(7, temp.PublicI);
temp.PublicI = 8;
Assert.Equal(8, temp.PublicI);
var po = new PrivateObject(temp);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
[Fact]
[Trait("Category", "Unit")]
public void TestMocked()
{
var mock = new Mock<Temp>(7);
Assert.Equal(7, mock.Object.PublicI);
mock.Object.PublicI = 8;
Assert.Equal(8, mock.Object.PublicI);
var po = new PrivateObject(mock.Object);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
// Following line throws System.MissingMethodException
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
}
</code>
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Xunit;
using Assert = Xunit.Assert;
namespace MyNamespace;
public class Temp
{
private int I { get; set; }
public int PublicI
{
get => I;
set => I = value;
}
public Temp(int i)
{
I = i;
}
}
public class Testing
{
[Fact]
[Trait("Category", "Unit")]
public void TestNormal()
{
var temp = new Temp(7);
Assert.Equal(7, temp.PublicI);
temp.PublicI = 8;
Assert.Equal(8, temp.PublicI);
var po = new PrivateObject(temp);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
[Fact]
[Trait("Category", "Unit")]
public void TestMocked()
{
var mock = new Mock<Temp>(7);
Assert.Equal(7, mock.Object.PublicI);
mock.Object.PublicI = 8;
Assert.Equal(8, mock.Object.PublicI);
var po = new PrivateObject(mock.Object);
var publicI = po.GetFieldOrProperty("PublicI");
Assert.Equal(8, publicI);
// Following line throws System.MissingMethodException
var privateI = po.GetFieldOrProperty("I", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.Equal(8, privateI);
}
}
The line after the comment throws a MissingMethodException
. Why doesn’t it find my member?