简体   繁体   English

如何使用moq框架在c#中编写私有方法的单元测试?

[英]How to write unit test for private method in c# using moq framework?

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. 我想在使用moq框架的C#中为私有方法编写单元测试,我在StackOverFlow和Google中搜索,但是我找不到预期的结果。 Please help me if you can. 如果可以,请你帮助我。

You can't, at least not with Moq. 你不能,至少不能与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. 其次,为了测试行为,您可以使用类型的公共 API并验证该练习的结果。

Private methods are implementation details. 私有方法是实现细节。 You don't want to verify how things get done, you want to verify that things do get done. 你不想以确定如何得到的东西做,你要验证事情得到完成。

Perhaps you shouldn't (see other answers for why), but you can do this using Microsoft's Visual Studio Test Tools . 也许你不应该(看其他答案为什么),但你可以使用微软的Visual Studio测试工具 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: 您可以使用以下代码来测试私有Duplicate方法:

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);
}

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: 在Moq你可以这样做:

var moq = new Mock<MyClass>();
moq.CallBase = true;
moq.Setup(x => x.MyPublicMethodToOverride()).Returns(true);

There are more details here . 还有更多的细节在这里

In the AssemblyInfo.cs of your project add 在您的项目的AssemblyInfo.cs中添加

[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. 然而正如dcastro所指出的,有些人强烈不同意这种测试方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM