Is Assert.Fail() considered bad practice?

前端 未结 14 1138
面向向阳花
面向向阳花 2021-01-31 07:20

I use Assert.Fail a lot when doing TDD. I\'m usually working on one test at a time but when I get ideas for things I want to implement later I quickly write an empty test where

相关标签:
14条回答
  • 2021-01-31 07:25

    Personally I have no problem with using a test suite as a todo list like this as long as you eventually get around to writing the test before you implement the code to pass.

    Having said that, I used to use this approach myself, although now I'm finding that doing so leads me down a path of writing too many tests upfront, which in a weird way is like the reverse problem of not writing tests at all: you end up making decisions about design a little too early IMHO.

    Incidentally in MSTest, the standard Test template uses Assert.Inconclusive at the end of its samples.

    AFAIK the xUnit.NET framework is intended to be extremely lightweight and yes they did cut Fail deliberately, to encourage the developer to use an explicit failure condition.

    0 讨论(0)
  • 2021-01-31 07:26

    I use MbUnit for my Unit Testing. They have an option to Ignore tests, which show up as Orange (rather than Green or Red) in the test suite. Perhaps xUnit has something similar, and would mean you don't even have to put any assert into the method, because it would show up in an annoyingly different colour making it hard to miss?

    Edit:

    In MbUnit it is in the following way:

    [Test]
    [Ignore]
    public void YourTest()
    { } 
    
    0 讨论(0)
  • 2021-01-31 07:28

    This is the pattern that I use when writting a test for code that I want to throw an exception by design:

    [TestMethod]
    public void TestForException()
    {
        Exception _Exception = null;
    
        try
        {
            //Code that I expect to throw the exception.
            MyClass _MyClass = null;
            _MyClass.SomeMethod();
            //Code that I expect to throw the exception.
        }
        catch(Exception _ThrownException)
        {   
            _Exception = _ThrownException
        }
        finally
        {
            Assert.IsNotNull(_Exception);
            //Replace NullReferenceException with expected exception.
            Assert.IsInstanceOfType(_Exception, typeof(NullReferenceException));
        }
    }
    

    IMHO this is a better way of testing for exceptions over using Assert.Fail(). The reason for this is that not only do I test for an exception being thrown at all but I also test for the exception type. I realise that this is similar to the answer from Matt Howells but IMHO using the finally block is more robust.

    Obviously it would still be possible to include other Assert methods to test the exceptions input string etc. I would be grateful for your comments and views on my pattern.

    0 讨论(0)
  • 2021-01-31 07:32

    Wild guess: withholding Assert.Fail is intended to stop you thinking that a good way to write test code is as a huge heap of spaghetti leading to an Assert.Fail in the bad cases. [Edit to add: other people's answers broadly confirm this, but with quotations]

    Since that's not what you're doing, it's possible that xUnit.Net is being over-protective.

    Or maybe they just think it's so rare and so unorthogonal as to be unnecessary.

    I prefer to implement a function called ThisCodeHasNotBeenWrittenYet (actually something shorter, for ease of typing). Can't communicate intention more clearly than that, and you have a precise search term.

    Whether that fails, or is not implemented (to provoke a linker error), or is a macro that doesn't compile, can be changed to suit your current preference. For instance when you want to run something that is finished, you want a fail. When you're sitting down to get rid of them all, you may want a compile error.

    0 讨论(0)
  • 2021-01-31 07:34

    I've always used Assert.Fail() for handling cases where you've detected that a test should fail through logic beyond simple value comparison. As an example:

    try 
    {
      // Some code that should throw ExceptionX
      Assert.Fail("ExceptionX should be thrown")
    } 
    catch ( ExceptionX ex ) 
    {
      // test passed
    }
    

    Thus the lack of Assert.Fail() in the framework looks like a mistake to me. I'd suggest patching the Assert class to include a Fail() method, and then submitting the patch to the framework developers, along with your reasoning for adding it.

    As for your practice of creating tests that intentionally fail in your workspace, to remind yourself to implement them before committing, that seems like a fine practice to me.

    0 讨论(0)
  • 2021-01-31 07:36

    This is our use case for Assert.Fail().

    One important goal for our Unit tests is that they don't touch the database.

    Sometimes mocking doesn't happen properly, or application code is modified and a database call is inadvertently made.

    This can be quite deep in the call stack. The exception may be caught so it won't bubble up, or because the tests are running initially with a database the call will work.

    What we've done is add a config value to the unit test project so that when the database connection is first requested we can call Assert.Fail("Database accessed");

    Assert.Fail() acts globally, even in different libraries. This therefore acts as a catch-all for all of the unit tests.

    If any one of them hits the database in a unit test project then they will fail.

    We therefore fail fast.

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