Do you use TestInitialize or the test class constructor to prepare each test? and why?

后端 未结 10 650
梦毁少年i
梦毁少年i 2020-12-02 15:35

This question regards unit testing in Visual Studio using MSTest (this is important, because of MSTest\'s execution order). Both the method marked [TestInitialize] and the t

相关标签:
10条回答
  • 2020-12-02 15:35

    I know I late to the party, but with async the is another reason (that does not existed when this question was ask) for [TestInitialize]. The allows you to do async operations to setup (eg. load a file) which is not possible in the constructor:

            private string approver;        
    
            [TestInitialize]
            public async Task Initialize()
            {
                approver = File.ReadAllTextAsync("approver.json");
            }
    
    0 讨论(0)
  • 2020-12-02 15:37

    The object you test doesn't need to be instantiated in the [TestInitialize] method. You can test the constructor of your object in a test method [Test].

    Object in the [TestInitialize] can be to setup your persistance storage or to prepare value that the object tested will used in the tests.

    0 讨论(0)
  • 2020-12-02 15:40

    This question is also asked (later) at What’s the difference between using the constructor in VS Testing framework vs. TestInitialize() attribute?

    FWIW I assume by "class constructor" you mean the instance constructor (not the static constructor).

    I believe the same question you are asking could equally be asked about the static constructor vs. ClassInitialize...

    0 讨论(0)
  • 2020-12-02 15:48

    The constructor is just a structure provided by the language. Every test framework seems has its own controlled lifecycle "initialize". You'll probably only get into trouble using the constructor to mutate your locals.

    MSTest: You get an entire new instance of the test class for every TestMethod. This might be the only case where it's ok to mutate your locals in the constructor, initializer, or test method and not affect the other test methods.

    public class TestsForWhatever
    {
        public TestsForWhatever()
        {
            // You get one of these per test method, yay!
        }
    
        [TestInitialize] 
        public void Initialize() 
        {
            // and one of these too! 
        }
    
        [TestMethod]
        public void AssertItDoesSomething() { }
    
        [TestMethod]
        public void AssertItDoesSomethingElse() { }
    }
    

    MSpec: You only get one Establish and Because for all your assertions (It). So, don't mutate your locals in your assertions. And don't depend on mutations of locals in base contexts (if you use them).

    [Subject(typeof(Whatever))]
    public class When_doing_whatever
    {
        Establish context = () => 
        { 
            // one of these for all your Its
        };
    
        Because of = () => _subject.DoWhatever();
    
        It should_do_something;
        It should_do_something_else;
    }
    
    0 讨论(0)
  • 2020-12-02 15:54

    I prefer to use the [TestInitialize] method to perform instantiation of the object being tested and it's parameters. I only perform work in the constructor if it is necessary to instantiate a testing base class (which is usually where I create or refresh repositories, etc). This helps me keep the test framework code and test code separate logically and physically.

    0 讨论(0)
  • 2020-12-02 15:54

    It depends on the scenario. If you have a test class, and for some weird reason if you need to create instance of it on another test class, you will need to use constructor.

    Otherwise test initialize more fits in the concept. Firstly, same reasons written above, second MS can introduce more features on that attribute and you will benefit them, with constructor you will stuck into it.

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