none
How to give assertion to the void methods in c#.net test framework ? RRS feed

  • Question

  • I can assert if method returns any value. But how can we assert to the void methods

    example :

    public void insert()

    {

    }

    Tuesday, December 29, 2015 11:14 AM

Answers

  • Or as we already said: It's an integration test.

    Integration and unit tests have several possible meanings. Admittedly the single developer testing his unit before passing it to someone else to test how it integrates into the bigger project is rare in .net nowadays. The terms don't emphasise the prime difference though.

    I prefer to use the fast and slow terminology because even someone who never heard of an integration or a unit test can understand fast and slow.

    Maybe I spend too much time talking to "non technical" management who don't understand why they need some extra server for testing.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Wednesday, December 30, 2015 3:51 PM
    Moderator
  • The first test using a testing framework is what is called a integration or functional test to verify that the DAL method worked for real hitting the database.

    The second one is a unit test, and  the assertion is the Excepted.Call(). If the method AddPayRoll () was never executed, test would fail.   

    using DAL;
    using NUnit.Framework;
    
    namespace FunctionalTest.DAL
    {
        [TestFixture]
        public class DoaAuthorTests
        {
            [Test]
            public void Should_Get_All_Authors()
            {
                var actuals = new DaoAuthor().GetAuthors();
                Assert.IsTrue(actuals.Count > 0);
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Services.IServices;
    using MbUnit.Framework;
    using Rhino.Mocks;
    using DemoApp.ViewModel;
    using BLL.DTO;
    
    namespace UnitTests
    {
        [TestFixture]
        public class PayRollViewModelTests
        {
            private MockRepository mMockRepo;
            private IService1 mMockService;
    
    
            [SetUp]
            public void Setup()
            {
                mMockRepo = new MockRepository();
                mMockService = mMockRepo.DynamicMock<IService1>();
           }
    
            [TearDown]
            public void TearDown()
            {
                mMockRepo.VerifyAll();
            }
    
            private PayRollViewModel CreateSUT()
            {
                mMockRepo.ReplayAll();
                return new PayRollViewModel(mMockService);
            }
    
            [Test]
            public void Test()
            {
                var payroll = new DTOPayroll {AuthorID = 1, PayRollID =  2, Salary =  77};
                
                CreateSUT().Salary = "2";
                CreateSUT().PayRollID = "2";
    
                Expect.Call(() => mMockService.AddPayRoll(payroll));
                Expect.Call(CreateSUT().Salary).Return("2");
            }
    
        }
    }
    

    Wednesday, December 30, 2015 3:00 PM

All replies

  • A void method cannot be side-effect free. Otherwise it would be useless.

    So you can use unit tests to check internal side-effects. Consider a class with a very complex algorithm based on some values:

    public class VeryComplexAlgorithm
    {
    	public double Area = 0;
    	public double Radius = 0;
    
    	public void CalculateVeryComplexAlgorithm()
    	{
    		this.Area = Math.Exp(this.Radius) * Math.PI;
    	}
    }


    So you would check whether the affected properties/fields contain the expected values after executing you method.

    But in this case this could be refactored to a better solution (some caching for performance :):

    public class VeryComplexAlgorithm
    {
    	private double? area = null;
    
    	public double Area
    	{
    		get
    		{
    			if (this.area==null)
    			{
    				this.CalculateVeryComplexAlgorithm();
    			}
    
    			return this.area.Value;
    		}
    	}
    
    	private double radius = 0;
    	public double Radius { get
    		{
    			return this.radius;
    		}
    		set
    		{
    			this.area = null;
    			this.radius = value;
    		}
    	}
    
    	private void CalculateVeryComplexAlgorithm()
    	{
    		this.area = Math.Exp(this.radius) * Math.PI;
    	}
    }
    

    Now you don't have any void method to test. Only properties.

    And last but not least: void methods with external side-effects are not tested with unit tests. They are tested with integration tests.

    Tuesday, December 29, 2015 11:44 AM
  • Not sure I understand the question.

    You can't return something from a void method anyway; you would get a syntax error if you tried.

    So what is there to assert?

    Tuesday, December 29, 2015 11:44 AM
  • Guess what, that is his question ;)
    Tuesday, December 29, 2015 11:47 AM
  • What are you talking about, the Assert statement in a UT framework?
    Tuesday, December 29, 2015 12:24 PM
  • Thanks for your comments. For example we have a method that working for insert operations

    Void Insert(int id,string sname)

    {

    try

    {

    }

    catch(exception ex)

    {

    }

    }

    How do we assert this method.

    Wednesday, December 30, 2015 10:19 AM
  • You've missed the point: Where do you insert that data?

    btw, post a concise and complete example. In your case your class under test and the test class.

    Wednesday, December 30, 2015 10:30 AM
  • class Service
        {
            public Service()
            {
    
            }
    
            public void Insert(int id,string sname)
            {
                try
                {
                    // Insert data into Emp table in 123sqlserver
                }
                catch(Exception ex)
                {
                    
                }
            }
        }

    This is my normal class. I did some code logic to insert data into sql server with service class, Insert method.

    My TestMethod like this

    [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void ValidateInsertService()
            {
                Service objService = new Service();
                objService.Insert(1, "EMPTEST");
                //How to assert above one.
            }
        }

    if the validateInsertService method returm type string means, we can validate with assetion.notnull and other.

    But how can i assert it ?

    Thanks,

    P.Maruthi


    Wednesday, December 30, 2015 12:53 PM
  • Your posted code does nothing. Really nothing. Thus there is nothing to test.

    Wednesday, December 30, 2015 1:35 PM
  • class Service
        {
            public Service()
            {
    
            }
    
            public void Insert(int id,string sname)
            {
                try
                {
                    // Insert data into Emp table in 123sqlserver
                }
                catch(Exception ex)
                {
                    
                }
            }
        }

    This is my normal class. I did some code logic to insert data into sql server with service class, Insert method.

    My TestMethod like this

    [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void ValidateInsertService()
            {
                Service objService = new Service();
                objService.Insert(1, "EMPTEST");
                //How to assert above one.
            }
        }

    if the validateInsertService method returm type string means, we can validate with assetion.notnull and other.

    But how can i assert it ?

    Thanks,

    P.Maruthi


    You are calling it a unit test, but it is not a unit test.

    http://www.artima.com/weblogs/viewpost.jsp?thread=126923

    That is an integration or functional test. The only thing you can do is have code to go read the inserted  data and do an Assert on the read code right after the insert to verify the data exists, which I would assume is an insert into a database table.

    If you were doing a unit test under the traditional sense of it being a unit test, then the Service would have been mocked out by using a mocking framework like Moq, Rhino Mocks or one of the other mocking frameworks.

    Wednesday, December 30, 2015 1:49 PM
  • To make it clear to you, the Assertion would be on the Insert() method actually being run in a mocking situation where the Service is mocked out.

    http://codetunnel.io/what-is-a-mocking-framework-why-is-it-useful/

    Wednesday, December 30, 2015 1:58 PM
  • Let's separate testing out into slow and fast tests.

    Fast tests use asserts and you run 2000 of the things every 10 minutes as you develop.

    Slow tests are those tests which you can't run 2000 every 10 minutes, these are usually run on a continuous integration server overnight.

    Any test which involves changes in a database is a slow test.

    You restore a database, run a bunch of them and check what you end up with in your database.

    When that doesn't match expectations a human being looks at what difference was found and works out which test failed.

    This should be relatively rare because your fast tests can check the objects you manipulate in order to make those changes.

    You check changes to properties etc.

    Whether an insert works or not cannot really be fast tested.

    You probably ought to be interested in whether an insert worked or not in your app though.

    Maybe that should be a bool rather than a void.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Wednesday, December 30, 2015 2:05 PM
    Moderator
  • Or as we already said: It's an integration test.

    Wednesday, December 30, 2015 2:11 PM
  • The first test using a testing framework is what is called a integration or functional test to verify that the DAL method worked for real hitting the database.

    The second one is a unit test, and  the assertion is the Excepted.Call(). If the method AddPayRoll () was never executed, test would fail.   

    using DAL;
    using NUnit.Framework;
    
    namespace FunctionalTest.DAL
    {
        [TestFixture]
        public class DoaAuthorTests
        {
            [Test]
            public void Should_Get_All_Authors()
            {
                var actuals = new DaoAuthor().GetAuthors();
                Assert.IsTrue(actuals.Count > 0);
            }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Services.IServices;
    using MbUnit.Framework;
    using Rhino.Mocks;
    using DemoApp.ViewModel;
    using BLL.DTO;
    
    namespace UnitTests
    {
        [TestFixture]
        public class PayRollViewModelTests
        {
            private MockRepository mMockRepo;
            private IService1 mMockService;
    
    
            [SetUp]
            public void Setup()
            {
                mMockRepo = new MockRepository();
                mMockService = mMockRepo.DynamicMock<IService1>();
           }
    
            [TearDown]
            public void TearDown()
            {
                mMockRepo.VerifyAll();
            }
    
            private PayRollViewModel CreateSUT()
            {
                mMockRepo.ReplayAll();
                return new PayRollViewModel(mMockService);
            }
    
            [Test]
            public void Test()
            {
                var payroll = new DTOPayroll {AuthorID = 1, PayRollID =  2, Salary =  77};
                
                CreateSUT().Salary = "2";
                CreateSUT().PayRollID = "2";
    
                Expect.Call(() => mMockService.AddPayRoll(payroll));
                Expect.Call(CreateSUT().Salary).Return("2");
            }
    
        }
    }
    

    Wednesday, December 30, 2015 3:00 PM
  • Or as we already said: It's an integration test.

    Integration and unit tests have several possible meanings. Admittedly the single developer testing his unit before passing it to someone else to test how it integrates into the bigger project is rare in .net nowadays. The terms don't emphasise the prime difference though.

    I prefer to use the fast and slow terminology because even someone who never heard of an integration or a unit test can understand fast and slow.

    Maybe I spend too much time talking to "non technical" management who don't understand why they need some extra server for testing.


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Wednesday, December 30, 2015 3:51 PM
    Moderator