using System; using Moq; namespace MoqSample { class Program { static void Main(string[] args) { // ARRANGE decimal amount = 100; // that's why you will love unit testing, mishaps could be avoided :-) string errorMessage = "Could be an anomaly, passed amount is different from amount to transfer"; var mockedSource = new Mock<IAccount>(); mockedSource.Setup(x => x.Withdraw(It.Is<decimal>(a => a != amount))).Throws(new Exception(errorMessage)); mockedSource.Setup(x => x.Deposit(It.Is<decimal>(a => a != amount))).Throws(new Exception(errorMessage)); var mockedDest = new Mock<IAccount>(); mockedDest.Setup(x => x.Withdraw(It.Is<decimal>(a => a != amount))).Throws(new Exception(errorMessage)); mockedDest.Setup(x => x.Deposit(It.Is<decimal>(a => a != amount))).Throws(new Exception(errorMessage)); // ACT int test = 0; /* * 0's error: NONE * * 1's error: * Expected invocation on the mock should never have been performed, but was 1 times: source => source.Deposit(.amount) * * 2's error: * Expected invocation on the mock once, but was 2 times: dest => dest.Deposit(.amount) * * 3's error: * Expected invocation on the mock once, but was 0 times: dest => dest.Deposit(.amount) * * 4's error: * Expected invocation on the mock once, but was 0 times: source => source.Withdraw(.amount) * * 5's error: * Could be an anomaly, passed amount is different from transfer amount * * */ if (test == 0) TransactionMaker.TransferFund(mockedSource.Object, mockedDest.Object, amount); else if (test == 1) TransactionMaker.TransferFundBuggy1(mockedSource.Object, mockedDest.Object, amount); else if (test == 2) TransactionMaker.TransferFundBuggy2(mockedSource.Object, mockedDest.Object, amount); else if (test == 3) TransactionMaker.TransferFundBuggy3(mockedSource.Object, mockedDest.Object, amount); else if (test == 4) TransactionMaker.TransferFundBuggy4(mockedSource.Object, mockedDest.Object, amount); else if (test == 5) TransactionMaker.TransferFundAnomalous(mockedSource.Object, mockedDest.Object, amount); else throw new Exception("Select test case from 0 to 5"); // ASSERT mockedSource.Verify(source => source.Withdraw(amount), Times.Once()); mockedSource.Verify(source => source.Deposit(amount), Times.Never()); mockedDest.Verify(dest => dest.Deposit(amount), Times.Once()); mockedDest.Verify(dest => dest.Withdraw(amount), Times.Never()); } } public static class TransactionMaker { public static void TransferFund(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Withdraw(amountToTransfer); destAccount.Deposit(amountToTransfer); } public static void TransferFundBuggy1(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Withdraw(amountToTransfer); sourceAccount.Deposit(amountToTransfer); } public static void TransferFundBuggy2(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Withdraw(amountToTransfer); destAccount.Deposit(amountToTransfer); destAccount.Deposit(amountToTransfer); } public static void TransferFundBuggy3(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Withdraw(amountToTransfer); } public static void TransferFundBuggy4(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Deposit(amountToTransfer); } public static void TransferFundAnomalous(IAccount sourceAccount, IAccount destAccount, decimal amountToTransfer) { sourceAccount.Withdraw(amountToTransfer); destAccount.Deposit(amountToTransfer + 0.5M); } } public interface IAccount { void Withdraw(decimal v); void Deposit(decimal v); } public class Account : IAccount { public void Withdraw(decimal amount) { } public void Deposit(decimal amount) { } } }
"Simplicity can't be bought later, it must be earned from the start" -- DB
Monday, February 27, 2012
A primer on unit testing with Moq
The following code is a primer on unit testing, just get Moq from Nuget. Note: Actual unit testing should be done on a separate project, not on Main method :-) This code just demonstrates how elegant Moq is for unit testing needs.
Labels:
Moq,
Unit Testing
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment