C# 单元测试中的静态类/方法/属性,是否停止
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10632975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static class/method/property in unit test, stop it or not
提问by Pingpong
Update
更新
should a static class/method/property be used in a unit test development environment, given that it is no way to test it without introducing a wrapper that is again not testable?
是否应该在单元测试开发环境中使用静态类/方法/属性,因为如果不引入再次不可测试的包装器就无法对其进行测试?
Another scenario is that when the static members are used within the unit tested target, the static memeber cannot be mocked. Thus, you have to test the static meembers when the unit tested target is tested. You want to isolate it when the static member performs calculation.
另一种情况是,当在单元测试目标中使用静态成员时,无法模拟静态成员。因此,您必须在测试单元测试目标时测试静态成员。你想在静态成员执行计算时隔离它。
采纳答案by k.m
Testing static method is no different than testing any other method. Having static method as a dependencyinside another tested module raises problems (as it's been mentioned - you can't mock/stub it with free tools). But if the static method itself is unit tested you can simply treat it as working, reliable component.
测试静态方法与测试任何其他方法没有什么不同。将静态方法作为另一个测试模块中的依赖项会引发问题(正如已经提到的 - 您不能使用免费工具模拟/存根它)。但是,如果静态方法本身经过单元测试,您可以简单地将其视为工作可靠的组件。
Overall, there's nothing wrong (as in, it doesn't disrupt unit testing/TDD) with static methods when:
总的来说,在以下情况下使用静态方法没有任何问题(例如,它不会中断单元测试/TDD):
- it is simple, input-output method (all kinds of "calculate this given that")
- it is reliable, by what we mean it's either unit tested by you or comes from 3rd party source you consider reliable (eg.
Math.Floormight be considered reliable - using it shouldn't raise "Look out, it's static!"warning; one might assume Microsoft does its job)
- 它很简单,输入输出方法(各种“计算这个给定那个”)
- 它是可靠的,我们的意思是它要么经过您的单元测试,要么来自您认为可靠的 3rd 方来源(例如,
Math.Floor可能被认为是可靠的 - 使用它不应引发“注意,它是静态的!”警告;人们可能会假设微软做它的工作)
When static methods will cause problems and should be avoided? Basically only when they interact with/do something you cannot control(or mock):
什么时候静态方法会导致问题并且应该避免?基本上只有当他们与您互动/做一些您无法控制(或模拟)的事情时:
- all kind of file system, database, network dependencies
- other (possibly more complex) static methods called from inside
- pretty much anything your mocking framework can't deal with on regular terms
- 各种文件系统、数据库、网络依赖
- 从内部调用的其他(可能更复杂的)静态方法
- 几乎任何你的模拟框架无法正常处理的东西
Edit:two examples on when static method willmake unit testing hard
编辑:关于静态方法何时会使单元测试变得困难的两个示例
1
1
public int ExtractSumFromReport(string reportPath)
{
var reportFile = File.ReadAllText(reportPath);
// ...
}
How do you deal with File.ReadAllText? This will obviously go to file system to retrieve file content, which is major no-no when unit testing. This is example of static method with external dependency. To avoid that, you usually create wrapper around file system api or simply inject it as dependency/delegate.
你怎么处理File.ReadAllText?这显然将转到文件系统以检索文件内容,这是单元测试时的主要禁忌。这是具有外部依赖性的静态方法的示例。为避免这种情况,您通常会在文件系统 api 周围创建包装器,或者只是将其作为依赖项/委托注入。
2
2
public void SaveUser(User user)
{
var session = SessionFactory.CreateSession();
// ...
}
What about this? Session is non-trivialdependency. Sure, it might come as ISession, but how do force SessionFactoryto return mock? We can't. And we can't create easy to deteminesession object either.
那这个呢?会话是非平凡的依赖。当然,它可能是ISession,但是如何强制SessionFactory返回模拟?我们不能。而且我们也不能创建易于确定的会话对象。
In cases like above, it's best to avoid static methods altogether.
在上述情况下,最好完全避免使用静态方法。
回答by Sergey Berezovskiy
You can't mock static methods/properties. So, when your classAuses some static member of classByou can't test classAin isolation.
您不能模拟静态方法/属性。因此,当您classA使用某些静态成员时,classB您无法单独进行测试classA。
UPDATE: I don't see any problem of wrapping some static class into object. It doesn't take lot of time, but it allows you to decrease coupling in your system.
更新:我没有看到将一些静态类包装到对象中的任何问题。这不会花费很多时间,但它可以让您减少系统中的耦合。
回答by serge.karalenka
回答by yegor256
Technically you canmock the static method in Java with PowerMock, but if you need to do this I would seriously recommend to refactor your code. I think that static methods should always be privateand used only inside the classes they are defined in, for internal purposes. I consider publicly exposed static method as a code smell.
从技术上讲,您可以使用PowerMock模拟 Java 中的静态方法,但如果您需要这样做,我强烈建议您重构您的代码。我认为静态方法应该始终private并且仅在它们定义的类中使用,用于内部目的。我认为公开暴露的静态方法是一种代码气味。
回答by Rozkalns
I find this threat regardless of the programming language, but since my daily life is related to PHP, here is good resource to deal with static methods on PHP http://docs.mockery.io/en/latest/reference/public_static_properties.html
无论编程语言如何,我都会发现这种威胁,但由于我的日常生活与 PHP 有关,这里是处理 PHP 静态方法的好资源http://docs.mockery.io/en/latest/reference/public_static_properties.html

