Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Greetings.

I have a method returning VOID and I have written below Unit test with "Microsoft.VisualStudio.TestTools.UnitTesting" for it. Is there any better alternative to do so?

What I have tried:

C#
using (var uow = new UOW.SalesEntityUOW())
{
    try
    {
        uow.MyMethodCall(); // This method will update data and return nothing.
    }
    catch (Exception ex)
    {
        Assert.IsFalse(true);
    }
    finally
    {
        Assert.IsTrue(true);
    }
}
Posted
Updated 15-Jun-18 9:06am
v3
Comments
Eric Lynch 4-Jun-18 22:04pm    
Difficult to say, from this snippet. Speaking generally, I would check the data that is altered and add an assertion for the accuracy of that alteration. For example, if you expected a data cell to be changed from 1 to 2, assert that the data cell is equal to 2, after the method is called.
F-ES Sitecore 5-Jun-18 7:17am    
It depends what the method does, however from the code you've posted it doesn't look like the method is unit testable. You can't unit test anything, it has to be written in a way that allows it.
GregoryPres 25-Jun-18 8:19am    
If that method changes the internal state, then you need to check the values of the members that were affected or validate the internal methods were called with the correct arguments.

1 solution

I would agree that as presented the test does not test the void method. It does not even verify that an expected exception is thrown when a certain condition arises. All it does it verify that something runs and does not throw an exception. Void method can be tested but you will need to look at the use of a mocking framework and some form of dependency injection. In TDD you should be developing the test before producing the code and therefore the test is defining what the code should do.

Here is sample of void method being tested:
/// <summary>
/// Creates the model.
/// </summary>
/// <param name="activityId">The activity identifier.</param>
/// <param name="documentModel">The document model.</param>
/// <exception cref="NotImplementedException"></exception>
public void CreateModel(string activityId, string documentModel)
{
    this.UpdateModel(activityId, documentModel);
}

it uses the following private method:
/// <summary>
/// Updates the model.
/// </summary>
/// <param name="activityId">The activity identifier.</param>
/// <param name="documentModel">The document model.</param>
public void UpdateModel(string activityId, string documentModel)
{
    FlattenedActivityModel activityModel = null;
    IAzureContainer azureContainer = ClassContainer.Resolve<IAzureContainer>();
    IPublishActivityEvents publisher = ClassContainer.Resolve<IPublishActivityEvents>();
    var searchQuery = string.Format(CultureInfo.CurrentCulture, "activityId:{0}", activityId);
    var activityModels = azureContainer.ActivitySearch(string.Empty, searchQuery);
    if (activityModels != null)
    {
        if (activityModels.Count > 0)
        {
            activityModel = activityModels[0];
        }
    }

    FlattenedDocumentModel model = new FlattenedDocumentModel(activityModel, documentModel);
    var metadata = JsonConvert.SerializeObject(model);
    publisher.PublishDocumentMetadata(metadata, activityModel.RootName, model.MetadataFileName);
}


One of the tests to validate the code would look like:

[TestMethod]
        public void When_CreateModel_Is_Called_Then_Model_Is_Created_As_Expected()
        {
            var activityContent = File.ReadAllText(@"TestData\FlattenedActivity.json");
            var activity = JsonConvert.DeserializeObject<FlattenedActivityModel>(activityContent);
            var documentRequest = File.ReadAllText(@"TestData\DocumentRequest.json");

            var activityId = Guid.NewGuid().ToString();
            var document1 = new FlattenedDocumentModel
            {
                DocumentId = Guid.NewGuid().ToString(),
                ActivityId = activityId
            };
            var documents = new Collection<FlattenedDocumentModel>
            {
                document1
            };
            var azureConatiner = new Mock<IAzureContainer>();

            var activities = new Collection<FlattenedActivityModel>();
            activity.ActivityId = activityId;
            activities.Add(activity);

            //get the activity
            var queryString = string.Format("activityId:{0}", activityId);
            azureConatiner.Setup(a => a.ActivitySearch(string.Empty, queryString)).Returns(activities);

            var publishActivityEvents = new Mock<IPublishActivityEvents>();

            // Register the components to the IOC container
            ClassContainer.InitialiseRegistrations();
            ClassContainer.RegisterInstance(azureConatiner.Object);
            ClassContainer.RegisterInstance(publishActivityEvents.Object);

            var target = new DocumentApi();
            target.UpdateModel(activityId, documentRequest);

            FlattenedDocumentModel expectedModel = new FlattenedDocumentModel(activity, documentRequest);
            var expectedMetadata = JsonConvert.SerializeObject(expectedModel);

            azureConatiner.Verify(a => a.ActivitySearch(string.Empty, queryString), Times.Once());
            publishActivityEvents.Verify(p => p.PublishDocumentMetadata(expectedMetadata, activity.RootName, expectedModel.MetadataFileName));
        }


This test verifies that the internals of the void method is making the expected calls, with the expected values and the expected number of times.(I would point out that this sample is WIP and has some issues that need further tests e.g. activityModel being null).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900