Moq – is useful framework that allows to simulate any functionality provided by object being tested. For example, you need to check is any method called in test scenario, so moq let you to do that. Just mock testable method, run scenario and detect is it being called at the end of test scenario.
Official documentation and examples allowed here – Quickstart.
And also i want to show one some helpful features for me. Read below.
Check did method was called inside object.
For example, you have logger interface and it’s implementation:
1 2 3 4 5 6 7 8 9 10 |
using System; namespace ... { public interface IIntegrationLog { void Error(string msg); void ExecuteWithLogging(Action action); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SharePoint; using Microsoft.SharePoint.Utilities; ... namespace ... { public class IntegrationLog: IIntegrationLog { ... public virtual void Error(string msg) { Log("Error", msg); } public void ExecuteWithLogging(Action action) { try { action.Invoke(); } catch (Exception ex) { this.Error(ex.Message); } } } } |
Major task is check did method Error was called inside and if it was, how mush times?
So, i wrote test class for it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace ... { [TestClass] public class IntegrationLogTests { private Mock<IntegrationLog> _integrationLog; // mocking testable object: // implementing method Error() taking string as argument [TestInitialize] public void TestInitialize() { this._integrationLog = new Mock<IntegrationLog>(); this._integrationLog.Setup(m => m.Error(It.IsAny<string>())); } // caller method not twrows any exceptions // so, => Error not called [TestMethod] public void ExecuteWithLogging_ExecuteWithLogging_Successed() { this._integrationLog.Object.ExecuteWithLogging(() => { return; }); this._integrationLog.Verify(m => m.Error("error"), Times.Never()); } // caller throws 1 exception [TestMethod] public void ExecuteWithLogging_ExecuteWithLogging_ExceptionCaught() { this._integrationLog.Object.ExecuteWithLogging(() => { throw new System.Exception("error"); }); this._integrationLog.Verify(m => m.Error("error"), Times.Once()); } // caller throws 2 exception [TestMethod] public void ExecuteWithLogging_ExecuteWithLogging_ExecuteWithLogging2Level() { this._integrationLog.Object.ExecuteWithLogging(() => { for (int i = 0; i < 2; i++) { this._integrationLog.Object.ExecuteWithLogging(() => { throw new System.Exception("error"); }); } }); this._integrationLog.Verify(m => m.Error("error"), Times.Exactly(2)); } // caller throws 3 exception [TestMethod] public void ExecuteWithLogging_ExecuteWithLogging_ExecuteWithLogging3Level() { this._integrationLog.Object.ExecuteWithLogging(() => { for (int i = 0; i < 2; i++) { this._integrationLog.Object.ExecuteWithLogging(() => { throw new System.Exception("error"); }); } throw new System.Exception("error"); }); this._integrationLog.Verify(m => m.Error("error"), Times.Exactly(3)); } } } |