Static class/method/property in unit test, stop it or not

后端 未结 5 2065
野性不改
野性不改 2020-12-03 07:37

Should a static class/method/property be used in a unit test development environment, given that there is no way to test it without introducing a wrapper that is again not t

相关标签:
5条回答
  • 2020-12-03 07:44

    You can't mock static methods/properties. So, when your classA uses some static member of classB you can't test classA in isolation.

    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.

    0 讨论(0)
  • 2020-12-03 07:48

    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

    0 讨论(0)
  • 2020-12-03 07:54

    Technically you can mock 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 private and used only inside the classes they are defined in, for internal purposes. I consider publicly exposed static method as a code smell.

    0 讨论(0)
  • 2020-12-03 07:59

    Static methods CAN be unit tested. They can't be mocked (generally; there are some frameworks to do this like Moles.

    0 讨论(0)
  • 2020-12-03 08:01

    Testing static method is no different than testing any other method. Having static method as a dependency inside 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:

    • 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.Floor might be considered reliable - using it shouldn't raise "Look out, it's static!" warning; one might assume Microsoft does its job)

    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 will make unit testing hard

    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.

    2

    public void SaveUser(User user)
    {
        var session = SessionFactory.CreateSession();
        // ...
    }
    

    What about this? Session is non-trivial dependency. Sure, it might come as ISession, but how do force SessionFactory to return mock? We can't. And we can't create easy to detemine session object either.

    In cases like above, it's best to avoid static methods altogether.

    0 讨论(0)
提交回复
热议问题