C# unit test file system




















Currently, the test method doesn't handle all the cases that it should. If the method under test, the Debit method, failed to throw an ArgumentOutOfRangeException when the debitAmount was larger than the balance or less than zero , the test method would pass. This is not good, because you want the test method to fail if no exception is thrown.

This is a bug in the test method. To resolve the issue, add an Assert. Fail assert at the end of the test method to handle the case where no exception is thrown. Rerunning the test shows that the test now fails if the correct exception is caught. The catch block catches the exception, but the method continues to execute and it fails at the new Assert. Fail assert. To resolve this problem, add a return statement after the StringAssert in the catch block.

Rerunning the test confirms that you've fixed this problem. The improvements to the test code led to more robust and informative test methods. But more importantly, they also improved the code under test. This walkthrough uses the Microsoft unit test framework for managed code. Test Explorer can also run tests from third-party unit test frameworks that have adapters for Test Explorer.

For more information, see Install third-party unit test frameworks. For information about how to run tests from a command line, see VSTest. Skip to main content. This browser is no longer supported. Download Microsoft Edge More info.

Contents Exit focus mode. Is this page helpful? Please rate your experience Yes No. Any additional feedback? Open Visual Studio. The New Project dialog box appears. Name the project Bank , and then click OK. Note If Program. On the start window, choose Create a new project. Note If you do not see the Console App template, you can install it from the Create a new project window. NET Core. The BankTests project is added to the Bank solution.

Note In Visual Studio version To rename the class, choose Yes in the dialog box that pops up and asks whether you want to also rename references to the code element. To rename the class, position the cursor on UnitTest1 in the code editor, right-click, and then choose Rename or press F2. Type in BankAccountTests and then press Enter.

You probably don't need to test that unless you're using an operating system which you're extremely unfamiliar with. So if you're simply giving a command to save files, for instance, it's a waste of time to write a test to make sure they really save. That the files get saved to the right place? Well, how do you know what the right place is?

Presumably you have code that combines a path with a file name. This is code you can test easily: Your input is two strings, and your output should be a string which is a valid file location constructed using those two strings. That you get the right set of files from a directory? You'll probably have to write a test for your file-getter class that really tests the file system. But you should use a test directory with files in it that won't change.

You should also put this test in an integration test project, because this is not a true unit test, because it depends on the file system. But, I need to do something with the files I get. For that test, you should use a fake for your file-getter class. Your fake should return a hard-coded list of files.

If you use a real file-getter and a real file-processor, you won't know which one causes a test failure. So your file-processor class, in testing, should make use of a fake file-getter class. Your file-processor class should take the file-getter interface. In real code, you'll pass in the real file-getter.

In test code you'll pass a fake file-getter that returns a known, static list. SystemWrapper wraps many of System. You can see the complete list. ReadAllBytes or whatever in the method under test, you could change it so that the IO is done outside and a stream is passed instead. This approach is a tradeoff. Firstly, yes, it is more testable. However, it trades testability for a slight addition to complexity.

This can hit maintainability and the amount of code you have to write, plus you may just move your testing problem up one level. However, in my experience this is a nice, balanced approach as you can generalise and make testable the important logic without committing yourself to a fully wrapped file system. Taking it a step further, mocking the filesystem can be a valid approach; it depends on how much bloat you're willing to live with. I've gone this route before; I had a wrapped file system implementation, but in the end I just deleted it.

There were subtle differences in the API, I had to inject it everywhere and ultimately it was extra pain for little gain as many of the classes using it weren't hugely important to me.

If I had been using an IoC container or writing something that was critical and the tests needed to be fast I might have stuck with it, though. As with all of these options, your mileage may vary. Inject your test doubles manually. Using an IoC container for testing would be overkill in the extreme! Maybe I am not understanding your second question, though.

This web site has a nice example showing you how to use injection for testing. Since , you can do that using Microsoft Fakes without the need to change your codebase for example because it was frozen already. Abstractions library. This provides interfaces and wrappers that you can use instead of creating your own. You still have to dependency inject the interface wrappers and mock them out in the unit tests. The downside is you have to add this third party dependency to all of your projects.

As always, carefully decide which option is better in your specific scenario. I would suggest starting simple, and once it gets too tedious to keep wrapping IO methods yourself, then switch over to System. Add the System. You can use your preferred mocking framework like Moq in this example , or you can use mocks provided in the System. TestingHelpers package. Thanks Marco. Abstractions instead of writing your own.



0コメント

  • 1000 / 1000