Sorry I should have investigated you problem more thoroughly. I didn't realize that PrivateObject
was an already existing class of the .NET framework.
My answer is not going to answer your problem directly but I'm leaving it here regardless. I assume you use Moq and therefore the following parts of classes are not available for mocking:
- non-virtual members
- static members
- extension methods
- any member of sealed classes
- fields
Private members can be tested, I'm not saying it's generally wrong. Usually the need to test private members is a sign of bad code design, though.
Private methods and fields are implementation details and should not affect your class' functionality. Don't treat each method as a unit, rather do treat the class as a unit. Test your class' behavior and that it does what it should do and don't test how it does it.
object result = privateObj.Invoke("DoSomething", txtBox, EventArgs.Empty);
You are calling the DoSomething
method on privateObj
and not on mockObj
which is not setup to return what you "need".
What should your unit test achieve? Mocking behavior of your system under test is kind of contradictory because test results will not be representative for the system's actual behavior.
I guess what you could do is to extract the functionality of SomeMethod
from PrivateObject
into a dependecy of it, let's say IHaveSomeMethod
.
public interface IHaveSomeMethod {
bool SomeMethod();
}
public class PrivateObject {
private IHaveSomeMethod dependency;
public PrivateObject(???SomeObject someObject???, IHaveSomeMethod ihsm) {
// ...
this.iHaveSomeMethod = ihsm;
// ...
}
public void DoSometing() {
// ...
iHaveSomeMethod.SomeMethod();
// ...
}
}
Then you could test like this
[TestMethod]
public void TestMethod()
{
TextBox txtBox= new TextBox() { Text = "Test" };
var mockObj = new Mock<IHaveSomeMethod>();
mockObj.Setup(x => x.Invoke("SomeMethod", It.IsAny<string>())).Returns(true);
var sut = new PrivateObject(???someObject???, mockObj.Object); // system under test
object result = sut.Invoke("DoSomething", txtBox, EventArgs.Empty);
Assert.AreEqual(txtBox.Text, string.Empty);
}