コード例 #1
0
        public void Execute_BalanceAfterWithdrawLowerThan500_NotifyLowerFunds()
        {
            // Arrange
            var fromAccountGuid = Guid.NewGuid();
            var email           = "*****@*****.**";

            var fromAccount = new Account
            {
                Balance = 1000m,
                Id      = fromAccountGuid,
                User    = new User
                {
                    Email = email
                },
                Withdrawn = 50m,
                PaidIn    = 50m
            };

            accountRepositoryMock
            .Setup(x => x.GetAccountById(fromAccountGuid))
            .Returns(fromAccount);

            // Act
            transferMoneyFeature.Execute(fromAccountGuid, 600m);

            // Assert
            notificationServiceMock.Verify(x => x.NotifyFundsLow(email), Times.Once);
        }
コード例 #2
0
 public void WithdrawMoneyExecuteThrowsError_InsufficientFunds()
 {
     Assert.Throws <InvalidOperationException>(() =>
     {
         _withdrawMoney.Execute(fromAccountId, 6500);
     });
 }
コード例 #3
0
        public void Execute_SmallAmount_TransferSuccessful()
        {
            withdrawMoney.Execute(fromAccount.Id, 500m);

            Assert.IsTrue(accountRepository.GetAccountById(fromAccount.Id).Balance == 1500m);
            Assert.IsTrue(accountRepository.GetAccountById(fromAccount.Id).Withdrawn == -500m);
        }
コード例 #4
0
        public void Execute_NotifiesLowFunds_WhenFundsAreLow(
            bool isFundsLow,
            int expectedNotifications)
        {
            // Arrange
            var mockAccount = new Mock <Account>(
                _fixture.Create <Guid>(),
                new User(
                    _fixture.Create <Guid>(),
                    _fixture.Create <string>(),
                    _fixture.Create <string>()),
                _fixture.Create <decimal>(),
                _fixture.Create <decimal>(),
                _fixture.Create <decimal>() * -1);

            mockAccount
            .Setup(o => o.IsFundsLow())
            .Returns(isFundsLow);

            _mockAccountRepository
            .Setup(ar => ar.GetAccountById(mockAccount.Object.Id))
            .Returns(mockAccount.Object);

            // Act
            _sut.Execute(mockAccount.Object.Id, _fixture.Create <decimal>());

            // Assert
            _mockNotificationService
            .Verify(ns => ns.NotifyFundsLow(mockAccount.Object.User.Email), Times.Exactly(expectedNotifications));
        }
コード例 #5
0
        public void SuccessfullyWithdrawMoneyFromAccount()
        {
            _sourceAccount = new Account(_sourceAccountGuid, _sourceUser, 850, 150, 1000);
            SetupTestAccount();
            withdrawMoneyService.Execute(_sourceAccountGuid, 200);

            var fromAccount = _testAccountRepository.GetAccountById(_sourceAccountGuid);

            fromAccount.Balance.Should().Be(650);
        }
コード例 #6
0
        public void Execute_InvalidFromAccountId_InvalidOperationException()
        {
            // Arrange
            Guid from = new Guid("11223344-5566-7788-99AA-BBCCDDEEFF03");

            _iAccountRepository.Setup(x => x.GetAccountById(from)).Returns(() => null);

            // Act
            Assert.Throws <InvalidOperationException>(() => _withdrawMoney.Execute(from, 500));

            // Assert
            _iAccountRepository.Verify(service => service.Update(null), Times.Never);
        }
コード例 #7
0
        public void SuccessfullyWithdrawMoneyFromAccount()
        {
            _sourceAccount = new Account(_sourceAccountGuid, _sourceUser, 850, 150, 1000);

            _accountRepositoryMock.Setup(x => x.GetAccountById(_sourceAccountGuid))
            .Returns(_sourceAccount);

            _accountRepositoryMock.Setup(x => x.Update(_sourceAccount)).Verifiable();

            withdrawMoneyService.Execute(_sourceAccountGuid, 200);

            _accountRepositoryMock.Verify(x => x.Update(_sourceAccount), Times.Once);
        }
コード例 #8
0
        public void ShouldExecuteSuccessfully(decimal balance, decimal withdrawn, decimal amount)
        {
            // Arrange
            var account = AccountFake(balance, withdrawn);

            _accountRepository.Setup(x => x.GetAccountById(account.Id))
            .Returns(account);

            // Act
            _feature.Execute(account.Id, amount);

            // Assert
            _accountRepository.Verify(x => x.Update(account), Times.Exactly(1));
        }
コード例 #9
0
        public void Exceute_When_Account_Has_Not_Sufficient_Amount(decimal withdrawAmount)
        {
            // Arrange
            var account = new Account
            {
                Balance = withdrawAmount - .000000000000000001m
            };

            _accountRepository.Setup(x => x.GetAccountById(It.IsAny <Guid>())).Returns(account);

            // Act

            // Assert
            Assert.Throws <InsufficientBalanceException>(() => _subject.Execute(Guid.NewGuid(), withdrawAmount));
        }
コード例 #10
0
        public void Execute_BalanceIsLessThanAmountToWithdraw_ThrowInvalidOperationException()
        {
            _fromAccount.Balance = 1m;
            var sut = new WithdrawMoney(_accountRepository.Object, _notificationService.Object);

            Assert.Throws <InvalidOperationException>(() => sut.Execute(_fromAccountId, 2m));
        }
コード例 #11
0
        public void WithdrawMoneyExecute_ExecutingWithdraw_RunsWithSuccess()
        {
            // Arrange

            var fromAccountId = Guid.NewGuid();

            var fromAccount = new Account();

            fromAccount.Balance   = 600m;
            fromAccount.Withdrawn = 500m;
            fromAccount.User      = new User();
            fromAccount.Id        = fromAccountId;

            var amount = 10;

            this.mockAccountRepository.Setup(x => x.GetAccountById(It.Is <Guid>(v => v.Equals(fromAccountId))))
            .Returns(fromAccount);


            var myWithdrawMoeny = new WithdrawMoney(this.mockAccountRepository.Object, this.mockNotificationService.Object);

            // Act

            myWithdrawMoeny.Execute(fromAccountId, amount);

            // Assert

            this.mockAccountRepository.Verify(x => x.GetAccountById(fromAccountId), Times.Once);

            this.mockNotificationService.Verify(x => x.NotifyApproachingPayInLimit(It.IsAny <string>()), Times.Never);
            this.mockNotificationService.Verify(x => x.NotifyFundsLow(It.IsAny <string>()), Times.Never);

            this.mockAccountRepository.Verify(x => x.Update(fromAccount), Times.Once);
        }
コード例 #12
0
        public void Execute_ShouldUpdateAccountSuccessfully()
        {
            // Arrange
            decimal amount = 500m;

            // As the withdrawal takes place succesfully, the account is being updated at the end.
            // However, if an exception is thrown, the Execute method will never reach
            // the update invocation.

            var from = new Account {
                Balance = 500m
            };                                         // simply change the account's balance to 499 or less to cause an insufficient funds exception and see this test failing.

            var mockAccountRepository   = new Mock <IAccountRepository>();
            var mockNotificationService = new Mock <INotificationService>();

            var fromID = Guid.NewGuid();

            from.User = new User {
                Email = "*****@*****.**", Id = fromID
            };

            var withdrawMoney = new WithdrawMoney(mockAccountRepository.Object, mockNotificationService.Object);

            mockAccountRepository.Setup(x => x.GetAccountById(It.Is <Guid>(y => y == fromID))).Returns(from);

            mockAccountRepository.Setup(y => y.Update(from));

            // Act
            withdrawMoney.Execute(fromID, amount);

            // Assert
            mockAccountRepository.Verify(y => y.Update(from));
        }
コード例 #13
0
        public void WithdrawMoney_Given_From_account_balance_is_less_than_500m_after_withdrawal_fire_a_notification_NotifyFundsLow()
        {
            var fromAccountGuid = new System.Guid("adc1c2b0-bb71-4205-bf95-91bdbda67d75");

            var user = new User()
            {
                Email = "*****@*****.**"
            };
            var fromAccount = new Account()
            {
                Balance = 1000m, User = user
            };


            var accountRepoMock         = new Mock <IAccountRepository>();
            var notificationServiceMock = new Mock <INotificationService>();

            accountRepoMock.Setup(xx => xx.GetAccountById(fromAccountGuid)).Returns(fromAccount);



            var sut = new WithdrawMoney(accountRepoMock.Object, notificationServiceMock.Object);

            sut.Execute(fromAccountGuid, 600.0m);

            Assert.AreEqual(400m, fromAccount.Balance);

            notificationServiceMock.Verify(x => x.NotifyFundsLow(fromAccount.User.Email), Times.Once);
        }
コード例 #14
0
        public void Execute_Successful()
        {
            const decimal amount = 200m;

            var accountRepository   = mockAccountRepository.Object;
            var notificationService = mockNotificationService.Object;

            var account = new Account(notificationService)
            {
                Id      = fromAccountId,
                Balance = 1000m
            };

            mockAccountRepository.Setup(x => x.GetAccountById(It.IsAny <Guid>()))
            .Returns(account);
            mockAccountRepository.Setup(x => x.Update(It.IsAny <Account>()));

            withdrawMoney = new WithdrawMoney(accountRepository);

            withdrawMoney.Execute(fromAccountId, amount);

            mockAccountRepository.Verify(x => x.GetAccountById(fromAccountId));

            mockAccountRepository.Verify(x => x.Update(account));

            Assert.AreEqual(800m, account.Balance);
        }
コード例 #15
0
        public void WithdrawMoney_ensure_withdrawn_is_updated_with_correct_amount()
        {
            var fromAccountGuid = new System.Guid("adc1c2b0-bb71-4205-bf95-91bdbda67d75");

            var user = new User()
            {
                Email = "*****@*****.**"
            };
            var fromAccount = new Account()
            {
                Balance = 1000m, User = user
            };


            var accountRepoMock         = new Mock <IAccountRepository>();
            var notificationServiceMock = new Mock <INotificationService>();

            accountRepoMock.Setup(xx => xx.GetAccountById(fromAccountGuid)).Returns(fromAccount);



            var sut = new WithdrawMoney(accountRepoMock.Object, notificationServiceMock.Object);

            sut.Execute(fromAccountGuid, 600.0m);


            Assert.AreEqual(-600m, fromAccount.Withdrawn);
        }
コード例 #16
0
        public void Execute_ShouldSendLowFundsNotification()
        {
            // Arrange
            decimal amount = 500m;

            var from = new Account {
                Balance = 999m
            };                                         // simply change the account's balance to 1000 to see this test fail

            // Since that the notification limit is 500, if the new balance falls under this limit
            // this test should pass. In order to test it, just change the balance and the amount
            // that is being send accordingly. If the new balance is equal to or more than 500 this test will fail.

            var mockAccountRepository   = new Mock <IAccountRepository>();
            var mockNotificationService = new Mock <INotificationService>();

            var fromID = Guid.NewGuid();

            from.User = new User {
                Email = "*****@*****.**", Id = fromID
            };

            var withdrawMoney = new WithdrawMoney(mockAccountRepository.Object, mockNotificationService.Object);

            mockAccountRepository.Setup(x => x.GetAccountById(It.Is <Guid>(y => y == fromID))).Returns(from);


            mockNotificationService.Setup(x => x.NotifyFundsLow(from.User.Email));

            // Act
            withdrawMoney.Execute(fromID, amount);

            // Assert
            mockNotificationService.Verify(x => x.NotifyFundsLow(from.User.Email));
        }
コード例 #17
0
        public void WithdrawMoney_SufficientFundsTest()
        {
            var accountId = Guid.NewGuid();
            var user      = new User {
                Id = Guid.NewGuid(), Name = "User", Email = ""
            };
            var account = new Account {
                Id = accountId, Balance = 100, User = user
            };

            IAccountRepository accounts = new MockAccountRepository();

            accounts.Add(account);

            var notificationService = new MockNotificationService();

            WithdrawMoney withdrawMoneyFeature = new WithdrawMoney(accounts, notificationService);

            withdrawMoneyFeature.Execute(accountId, 100);

            account = accounts.GetAccountById(accountId);

            Assert.AreEqual(0, account.Balance);
            Assert.AreEqual(-100, account.Withdrawn);
        }
コード例 #18
0
        public void Execute_ShouldThrowInsufficientFundsException()
        {
            // Arrange
            decimal amount = 500m;

            var from = new Account {
                Balance = 499m
            };                                            // Since that the the exception would be thrown if the new balance is less than 0 and we send 500,
                                                          // then if the value of account's balance changes to 500 or more this test will fail.

            var mockAccountRepository   = new Mock <IAccountRepository>();
            var mockNotificationService = new Mock <INotificationService>();

            var fromID = Guid.NewGuid();

            from.User = new User {
                Email = "*****@*****.**", Id = fromID
            };

            var withdrawMoney = new WithdrawMoney(mockAccountRepository.Object, mockNotificationService.Object);

            mockAccountRepository.Setup(x => x.GetAccountById(It.Is <Guid>(y => y == fromID))).Returns(from);

            // Act & Assert
            Assert.Throws <InvalidOperationException>(() => withdrawMoney.Execute(fromID, amount));
        }
コード例 #19
0
        public void WithdrawMoney_InsufficientFundsTest()
        {
            var accountId = Guid.NewGuid();
            var user      = new User {
                Id = Guid.NewGuid(), Name = "User", Email = ""
            };
            var account = new Account {
                Id = accountId, Balance = 0, User = user
            };

            IAccountRepository accounts = new MockAccountRepository();

            accounts.Add(account);

            var notificationService = new MockNotificationService();

            WithdrawMoney withdrawMoneyFeature = new WithdrawMoney(accounts, notificationService);

            try
            {
                withdrawMoneyFeature.Execute(accountId, 100);
            }
            catch (InvalidOperationException ex)
            {
                if (ex.Message == "Insufficient funds to make transfer")
                {
                    return;
                }
            }
            Assert.Fail();
        }
コード例 #20
0
        public void WithdrawMoney_Ensure_that_account_repo_is_called_to_update_account()
        {
            var fromAccountGuid = new System.Guid("adc1c2b0-bb71-4205-bf95-91bdbda67d75");

            var user = new User()
            {
                Email = "*****@*****.**"
            };
            var fromAccount = new Account()
            {
                Balance = 1000m, User = user
            };


            var accountRepoMock         = new Mock <IAccountRepository>();
            var notificationServiceMock = new Mock <INotificationService>();

            accountRepoMock.Setup(xx => xx.GetAccountById(fromAccountGuid)).Returns(fromAccount);



            var sut = new WithdrawMoney(accountRepoMock.Object, notificationServiceMock.Object);

            sut.Execute(fromAccountGuid, 600.0m);

            Assert.AreEqual(400m, fromAccount.Balance);
            accountRepoMock.Verify(x => x.Update(It.IsAny <Account>()), Times.Once);
        }
コード例 #21
0
        public void Withdraw_Insufficient_Funds()
        {
            var withdrawAmount = 1001m;

            var withdrawMoneyFeature = new WithdrawMoney(_mockAccountRepository.Object, _mockNotificationService.Object);

            Assert.Throws <InvalidOperationException>(() => withdrawMoneyFeature.Execute(this._fromAccount.Id, withdrawAmount));
        }
コード例 #22
0
        public void Execute_UpdatesAccountInRepo_When_SufficientFunds()
        {
            var withdrawMoney = new WithdrawMoney(accountRepository.Object, notificationService.Object);

            withdrawMoney.Execute(accountguid, 100);

            accountRepository.Verify(x => x.Update(account), Times.AtLeast(1));
        }
コード例 #23
0
        public void TestInsufficientFunds()
        {
            PopulateData();
            var withdrawMoney = new WithdrawMoney(_accountRepository.Object, _notificationService.Object);
            var ex            = Assert.Throws <InvalidOperationException>(() => withdrawMoney.Execute(fromAccount.Id, 2500));

            Assert.That(ex.Message.Equals($"Insufficient funds for {fromAccount.User.Name}"));
        }
コード例 #24
0
        public void ExceptionThrownOnInsufficientFunds()
        {
            var amount = TestAccountFactory.DefaultBalance + 1m;

            Action withdrawalAction = () => withdrawMoney.Execute(
                TestAccountFactory.Ids.DefaultFrom,
                amount);

            withdrawalAction.Should().Throw <InvalidOperationException>();

            // Ensure that no notifications were sent
            NotificationServiceMock.Verify(x => x.NotifyApproachingPayInLimit(It.IsAny <string>()), Times.Never);
            NotificationServiceMock.Verify(x => x.NotifyFundsLow(It.IsAny <string>()), Times.Never);

            // Ensure that the account was not updated
            AccountRepositoryMock.Verify(x => x.Update(It.IsAny <Account>()), Times.Never);
        }
コード例 #25
0
        public void Execute_DoesNotUpdateAccountInRepo_When_InsufficientFunds()
        {
            var withdrawMoney = new WithdrawMoney(accountRepository.Object, notificationService.Object);

            var exception = Assert.Throws <InvalidOperationException>(() => withdrawMoney.Execute(accountguid, 4001m));

            accountRepository.Verify(x => x.Update(account), Times.Never);
        }
コード例 #26
0
        public void Withdraw_Sufficient_Funds()
        {
            var withdrawAmount = 1000m;

            var withdrawMoneyFeature = new WithdrawMoney(_mockAccountRepository.Object, _mockNotificationService.Object);

            withdrawMoneyFeature.Execute(this._fromAccount.Id, withdrawAmount);
        }
コード例 #27
0
        public void ValidateSufficientWithdrawFundsSuccess()
        {
            var amountToWithdraw = 1001;

            var withdrawMoney = new WithdrawMoney(_accountRepositoryMock.Object);

            withdrawMoney.Execute(_fromAccountId, amountToWithdraw);
        }
コード例 #28
0
        public void TestFundsIsLow()
        {
            PopulateData();
            var withdrawMoney = new WithdrawMoney(_accountRepository.Object, _notificationService.Object);

            withdrawMoney.Execute(fromAccount.Id, 1800);
            _notificationService.Verify(x => x.NotifyFundsLow(fromAccount.User.Email));
            _accountRepository.Verify(x => x.Update(fromAccount));
        }
コード例 #29
0
        public void Execute_BalanceBecomesLowerThanThreshold500_SendNotification()
        {
            _fromAccount.Balance = 500m;
            var sut = new WithdrawMoney(_accountRepository.Object, _notificationService.Object);

            sut.Execute(_fromAccountId, 1m);

            _notificationService.Verify(n => n.NotifyFundsLow(_fromUser.Email));
        }
コード例 #30
0
        public void TestSufficentWithdraw()
        {
            decimal       startBalance         = this.testFromAccount.Balance;
            WithdrawMoney withdrawMoneyFeature = new WithdrawMoney(accountRepository.Object, notificationService.Object);

            withdrawMoneyFeature.Execute(testFromAccount.Id, 10.0m);

            Assert.AreEqual(this.testFromAccount.Balance, startBalance - 10.0m);
        }