Last active
February 20, 2021 14:44
-
-
Save olegon/1a3d88ba558696cec8b87c5bcea1bfe4 to your computer and use it in GitHub Desktop.
Unit testing .xlsx file parsing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Globalization; | |
using System.IO; | |
using System.Threading.Tasks; | |
using ClosedXML.Excel; | |
namespace application | |
{ | |
public class App | |
{ | |
private readonly IFakeRepository _fakeRepository; | |
private readonly CultureInfo _cultureInfo; | |
public App( | |
IFakeRepository fakeRepository | |
) | |
{ | |
this._fakeRepository = fakeRepository; | |
this._cultureInfo = new CultureInfo("pt-BR"); | |
} | |
public async Task ParseWorkbookFile(Stream stream) | |
{ | |
using (var wb = new XLWorkbook(stream)) | |
{ | |
var sheet = wb.Worksheet(1); | |
foreach (var row in sheet.RowsUsed()) | |
{ | |
var rowNumber = row.RowNumber(); | |
if (rowNumber > 2) | |
{ | |
try | |
{ | |
var accountId = GetAccountId(row); | |
var reason = GetReason(row); | |
var amount = GetAmount(row); | |
var description = GetDescription(row); | |
await _fakeRepository.InsertLine( | |
lineNumber: rowNumber, | |
status: "VALID", | |
accountId: accountId, | |
reason: reason, | |
amount: amount, | |
description: description | |
); | |
} | |
catch (System.Exception ex) | |
{ | |
await _fakeRepository.InsertLine( | |
lineNumber: rowNumber, | |
status: "INVALID", | |
invalidReason: ex.Message | |
); | |
} | |
} | |
} | |
} | |
} | |
private string GetAccountId(IXLRow row) | |
{ | |
var value = row.Cell(1).GetString(); | |
return value; | |
} | |
private string GetReason(IXLRow row) | |
{ | |
var value = row.Cell(2).GetString(); | |
return value; | |
} | |
private double GetAmount(IXLRow row) | |
{ | |
var value = row.Cell(3).GetString(); | |
try | |
{ | |
return double.Parse(value, NumberStyles.Currency, _cultureInfo); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Amount out of the expected format.", ex); | |
} | |
} | |
private string GetDescription(IXLRow row) | |
{ | |
var value = row.Cell(4).GetString(); | |
return value; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Threading.Tasks; | |
using application; | |
using application_tests.WorkbookUtils; | |
using FakeItEasy; | |
using NUnit.Framework; | |
namespace application_tests | |
{ | |
public class AppTests | |
{ | |
private IFakeRepository _fakeRepository; | |
private App _app; | |
[SetUp] | |
public void Setup() | |
{ | |
_fakeRepository = A.Fake<IFakeRepository>(); | |
_app = new App( | |
fakeRepository: _fakeRepository | |
); | |
} | |
[Test] | |
public async Task Test1() | |
{ | |
var wbBuilder = new WorkbookBuilder(); | |
wbBuilder.AddLine("V1"); | |
wbBuilder.AddLine("AccountId", "Motivo", "Valor", "Descrição"); | |
wbBuilder.AddLine("001", "Motivo 01", "R$ 10,00", "Desc 01"); | |
wbBuilder.AddLine("002", "Motivo 02", "", "Desc 02"); | |
using (var ms = wbBuilder.GetStream()) | |
{ | |
await _app.ParseWorkbookFile(ms); | |
} | |
A.CallTo(() => _fakeRepository.InsertLine(1, A<string>.Ignored, A<string>.Ignored)).MustNotHaveHappened(); | |
A.CallTo(() => _fakeRepository.InsertLine(2, A<string>.Ignored, A<string>.Ignored)).MustNotHaveHappened(); | |
A.CallTo(() => _fakeRepository.InsertLine(3, "VALID", "001", "Motivo 01", 10, "Desc 01")).MustHaveHappened(); | |
A.CallTo(() => _fakeRepository.InsertLine(4, "INVALID", "Amount out of the expected format.")).MustHaveHappened(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Threading.Tasks; | |
namespace application | |
{ | |
public class FakeRepository : IFakeRepository | |
{ | |
public async Task InsertLine(int lineNumber, string status, string accountId, string reason, double amount, string description) | |
{ | |
await System.Console.Out.WriteLineAsync($"{lineNumber}, {status}, {accountId}, {reason}, {amount}, {description}"); | |
} | |
public async Task InsertLine(int lineNumber, string status, string invalidReason) | |
{ | |
await System.Console.Out.WriteLineAsync($"{lineNumber}, {status}, {invalidReason}"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Threading.Tasks; | |
namespace application | |
{ | |
public interface IFakeRepository | |
{ | |
Task InsertLine( | |
int lineNumber, | |
string status, | |
string accountId, | |
string reason, | |
double amount, | |
string description | |
); | |
Task InsertLine( | |
int lineNumber, | |
string status, | |
string invalidReason | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.IO; | |
using ClosedXML.Excel; | |
namespace application_tests.WorkbookUtils | |
{ | |
public class WorkbookBuilder | |
{ | |
private readonly List<object[]> _lines; | |
public WorkbookBuilder() | |
{ | |
_lines = new List<object[]>(); | |
} | |
public WorkbookBuilder AddLine(params object[] values) | |
{ | |
this._lines.Add(values); | |
return this; | |
} | |
public Stream GetStream() | |
{ | |
var ms = new MemoryStream(); | |
using (var wb = new XLWorkbook()) | |
{ | |
var sheet = wb.AddWorksheet(); | |
for (int lineNumber = 0; lineNumber < _lines.Count; lineNumber++) | |
{ | |
var lineValues = _lines[lineNumber]; | |
for (int columnNumber = 0; columnNumber < lineValues.Length; columnNumber++) | |
{ | |
var cellValue = lineValues[columnNumber]; | |
sheet.Row(lineNumber + 1).Cell(columnNumber + 1).SetValue(cellValue); | |
} | |
} | |
wb.SaveAs(ms); | |
} | |
return ms; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment