Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NUnit - Unit test case to test Transaction

I have a method as below.

I would like to write two test cases for the below method.

1) A successful transaction with committing data

2) A failed transaction with rollback data

How can I write a test case with transaction involved and make success and fail?

public async Task<List<string>> UpdateRequest(MetaData data, List<string> Ids, string requestedBy)
{
    var transaction = await _databaseUtility.CreateTransaction(ConnectionString);

    var messages = new List<string>();

    try
    {
        // Update data
        await _testDal.Update(data, requestedBy, transaction);

        // Update status
        await _sampleDal.UpdateStatus(Ids, requestedBy, transaction);

        // Update saved data
        await _testDal.UpdateSavedData(data, requestedBy, transaction);

        _databaseUtility.CommitTransaction(transaction);
    }
    catch (Exception exception)
    {
        _databaseUtility.RollbackTransaction(transaction);
    }

    return messages;
}
like image 488
Chatra Avatar asked Nov 05 '19 16:11

Chatra


Video Answer


1 Answers

I think you have 2 problems here:

  1. you are using async and await in unit testing which means your code will continue to run before anything was really done.
    you can read this https://johnthiriet.com/removing-async-void/#

    i will explain the catch, make sure await _testDal.Update(data, requestedBy, transaction); Update() function returns a Task.
    And then you can call it with _testDal.Update(data, requestedBy, transaction).Wait() for unit testing.
    and the await call for your regular code. this will make your testing code wait until Update finishes, while the regular code stays as is.

  2. I would use a mocking service like NSubstitute https://nsubstitute.github.io/ in order to mock the responses. a mocking service will use reflection to replace the interface or class which implements _testDal.
    this way when you call Update() function you can pass certain paramters to it and throw an exception when those parameters are passed into the function.
    And pass another set of parameters and return the correct messages for them.

if you wish to pass different parameters you can use Nunit TestCase(new[] params...) and pass a different set of parameters to the same unit tests. however for PassTest and FailTest i would use 2 or more different tests.

like image 111
Gilad Avatar answered Sep 18 '22 11:09

Gilad