public async void Option1____WhenGivenADateTimeOtherThanMinValue_ShouldPassItToRepository() { /* Option 1 * ================ * * To inspect the expression passed in, we'll use a Callback in Moq to interrogate the parameter sent to * the Repository's GetItems method. * * Rather than parse the Expression Tree, we'll compile it and pass in some values that would prove it's * doing what we expect. * * I'm not a big fan of this, since we're "blackbox" testing the Expression, which works, but isn't ideal. * * Also, this test is now HUGE in comparison to other tests. */ // Arrange // Note: Rather than using just "DateTime.Today", I'm randomizing the date. This way, if the SUT has // "DateTime.Today" hardcoded, the test will fail. var rando = new Random().Next(1, 100); var input = DateTime.Today.AddDays(rando); var repository = new Mock <IFiscalDataRepository>(); repository .Setup(x => x.GetItems(It.IsAny <Expression <Func <IFiscalData, bool> > >())) .Returns(Task.FromResult((IEnumerable <IFiscalData>) new IFiscalData[] { })) .Callback <Expression <Func <IFiscalData, bool> > >(expr => { // Assert var compiledExpr = expr.Compile(); var matchingDate = new FiscalData { Date = input }; var nonMatchingDate1 = new FiscalData { Date = input.AddDays(1) }; var nonMatchingDate2 = new FiscalData { Date = input.AddDays(-1) }; var matchingResult = compiledExpr(matchingDate); var nonMatchingResult1 = compiledExpr(nonMatchingDate1); var nonMatchingResult2 = compiledExpr(nonMatchingDate2); Assert.True(matchingResult); Assert.False(nonMatchingResult1); Assert.False(nonMatchingResult2); }); // Act var service = new FiscalDataService(repository.Object, null); await service.GetFiscalData(input); }
public async void WhenNullReturnedFromRepository_ShouldThrowNoDataFoundException() { // Arrange var repository = new Mock <IFiscalDataRepository>(); repository .Setup(x => x.GetItems(It.IsAny <Expression <Func <IFiscalData, bool> > >())) .Returns(Task.FromResult((IEnumerable <IFiscalData>)null)); // Act + Assert var service = new FiscalDataService(repository.Object, null); await Assert.ThrowsAsync <NoDataFoundException>( async() => { await service.GetFiscalData(DateTime.Now); } ); }
public async void ShouldReturnTheFiscalDataObjectFromTheRepository() { // Arrange var expected = new FiscalData(); var repository = new Mock <IFiscalDataRepository>(); repository .Setup(x => x.GetItems(It.IsAny <Expression <Func <IFiscalData, bool> > >())) .Returns(Task.FromResult((IEnumerable <IFiscalData>) new[] { expected })); // Act var service = new FiscalDataService(repository.Object, null); var actual = await service.GetFiscalData(DateTime.Today); // Assert Assert.Equal(expected, actual); }
public async void ShouldCallTheRepositorysGetItemsMethod() { // Arrange var repository = new Mock <IFiscalDataRepository>(); repository .Setup(x => x.GetItems(It.IsAny <Expression <Func <IFiscalData, bool> > >())) .Returns(Task.FromResult((IEnumerable <IFiscalData>) new List <IFiscalData>())) .Verifiable(); // Act var service = new FiscalDataService(repository.Object, null); await service.GetFiscalData(DateTime.Today); // Assert repository.Verify(); }
public async void Option2____WhenGivenADateTimeOtherThanMinValue_ShouldPassItToRepository() { /* Option 2 * ================ * * To inspect the expression passed in, we'll use a Callback in Moq to interrogate the * parameter sent to the Repository's GetItems method. * * If we know (and we should) that the Expression used will be a BinaryExpression with the * variable on the Right side, we can grab, then compile, that piece and compare its value * to our input. * * This method is not perfect either, as it's convoluted to write - especially before coding * the class - and I can see annoying maintenance issues with it. That said, it probably is a * better test than Option1, as its "whitebox" nature helps reduce false positives. * */ // Arrange var input = DateTime.Today.AddDays(new Random().Next(1, 100)); var repository = new Mock <IFiscalDataRepository>(); repository .Setup(x => x.GetItems(It.IsAny <Expression <Func <IFiscalData, bool> > >())) .Returns(Task.FromResult((IEnumerable <IFiscalData>) new IFiscalData[] { })) .Callback <Expression <Func <IFiscalData, bool> > >(expr => { // Assert var memberExpr = (expr.Body as BinaryExpression)?.Right as MemberExpression; // Using Assert.True(...) as xUnit doesn't support messages on Assert.NotNull(...) Assert.True(memberExpr != null, "Unable to convert expression into usable form"); var exprValue = memberExpr.GetValue(); Assert.Equal(input, exprValue); }); // Act var service = new FiscalDataService(repository.Object, null); await service.GetFiscalData(input); }