how to properly test an abstract class

前端 未结 2 672
耶瑟儿~
耶瑟儿~ 2021-01-13 07:34

I\'m currently in the process of creating a unit test for an abstract class, called Component. VS2008 compiled my program no problems so I was able to create a

2条回答
  •  无人共我
    2021-01-13 08:21

    This is how I do it. With a inner-nested-class on the UnitTest class.

    namespace MyCompany.MyProject.UnitTests
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Threading.Tasks;
        using Microsoft.VisualStudio.TestTools.UnitTesting;
        using FluentAssertions;
    
        [TestClass]
        [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
        public class MyAbstractClassTests
        {
            [TestMethod]
            public void ConstructorILoggerFactoryIsNullTest()
            {
                Action a = () => new MyUnitTestConcreteClass(null);
                a.Should().Throw().WithMessage(MyAbstractClass.ErrorMessageILoggerFactoryIsNull);
    
            }
    
            [TestMethod]
            public void GetABooleanIsTrueTest()
            {
                /* here is more likely what you want to test..an implemented method on the abstract class */
                Mock iloggerFactoryMock = this.GetDefaultILoggerFactoryMock();
                MyUnitTestConcreteClass testItem = new MyUnitTestConcreteClass(iloggerFactoryMock.Object);
                Assert.IsTrue(testItem.GetABoolean());
            }   
    
            [TestMethod]
            public void GetSomeIntsIsNotNullTest()
            {
                /* you may not want to test the abstract methods, but you can */
                Mock iloggerFactoryMock = this.GetDefaultILoggerFactoryMock();
                MyUnitTestConcreteClass testItem = new MyUnitTestConcreteClass(iloggerFactoryMock.Object);
                Assert.IsNotNull(testItem.GetSomeInts());
            }       
    
    
            private Mock GetDefaultILoggerFactoryMock()
            {
                Mock returnMock = new Mock(MockBehavior.Strict);
                ////returnMock.Setup(x => x.SomeBooleanMethod()).Returns(true);
                return returnMock;
            }       
    
    
    
            internal class MyUnitTestConcreteClass : MyAbstractClass
            {
                internal MyUnitTestConcreteClass(ILoggerFactory loggerFactory) : base(loggerFactory)
                {
                }
    
                public override ICollection GetSomeInts()
                {
                    return new List { 111, 222, 333 };
                }
            }
        }
    }
    

    and the "real" abstract class below

    public abstract class MyAbstractClass : where T : struct
    {
    
        public const string ErrorMessageILoggerFactoryIsNull = "ILoggerFactory is null";
    
        public WhiteListStepBodyAsyncBase(ILoggerFactory loggerFactory)
        {
            if (null == loggerFactory)
            {
                throw new ArgumentNullException(ErrorMessageILoggerFactoryIsNull, (Exception)null);
            }
    
        }           
    
        public bool GetABoolean()
        {
              /* note , this is important factor (sometimes), here this implemented method DEPENDS on an abstract method , and why I have the code "return new List { 111, 222, 333 };" above .. see the connection ?? */
                        return this.GetSomeInts().Count > 0;
        }
    
        public abstract ICollection GetSomeInts();
    
    
    }
    

    This question is older, but the principals are the same.

    Here are my VS2019, year 2020 .. package imports.

      
        
          all
          runtime; build; native; contentfiles; analyzers; buildtransitive
        
        
        
        
        
        
        
        
    

提交回复
热议问题