问题
I want to write unit test for private method in C# using moq framework, I've search in StackOverFlow and Google, but I cannot find the expected result. Please help me if you can.
回答1:
You can't, at least not with Moq.
But more importantly, you shouldn't. First off, you don't test methods, you test behaviours. Second, in order to test behaviours, you exercise a type's public API and verify the outcomes of that exercise.
Private methods are implementation details. You don't want to verify how things get done, you want to verify that things do get done.
回答2:
Perhaps you shouldn't (see other answers for why), but you can do this using Microsoft's Visual Studio Test Tools. A simplified example is given below.
Given the following class which you want to test:
public class ClassToTest
{
private int Duplicate(int n)
{
return n*2;
}
}
You can use the following code to test the private Duplicate
method:
using Microsoft.VisualStudio.TestTools.UnitTesting;
// ...
[TestMethod]
public void MyTestMethod()
{
// Arrange
var testClass = new ClassToTest();
var privateObject = new PrivateObject(testClass);
// Act
var output = (int) privateObject.Invoke("Duplicate", 21);
// Assert
Assert.AreEqual(42, output);
}
回答3:
In the AssemblyInfo.cs of your project add
[assembly: InternalsVisibleTo("Namespace.OfYourUnitTest.Project")]
then you make the method internal instead of private.
It has the benefit of avoiding to make it public.
However as pointed by dcastro, some people strongly disagree with this way of testing.
回答4:
Simply, you don't. Private methods are not visible to other classes.
There are a number of ways around this:
- Treat the private as part of the method you're testing, cover it in their unit tests. Think of the public methods as black boxes and test their operations.
- Make it protected and inherit your test class from the class you're testing (or use a partial - same idea)
- Make it public (which if you're coding to an interface doesn't actually expose it to your consumers)
For public methods (option three) it is possible to partial mock the class where you can replace the method. In Moq you can do this like this:
var moq = new Mock<MyClass>();
moq.CallBase = true;
moq.Setup(x => x.MyPublicMethodToOverride()).Returns(true);
There are more details here.
来源:https://stackoverflow.com/questions/25237971/how-to-write-unit-test-for-private-method-in-c-sharp-using-moq-framework