public class ArticleManagerTest extends SampleBaseTestCase { @Mock private ArticleCalculator calculator; @Mock(name = "database") private ArticleDatabase dbMock; // note the mock name attribute @Spy private UserProvider userProvider = new ConsumerUserProvider(); @InjectMocks private ArticleManager manager; @Test public void shouldDoSomething() { manager.initiateArticle(); verify(database).addListener(any(ArticleListener.class)); } } public class SampleBaseTestCase { @Before public void initMocks() { MockitoAnnotations.initMocks(this); } }In the example above annotations are used to create fake objects and a real object which uses them. The end result is very similar to using an AutoMocking container.
I’ve created a simple attribute to mark fields that I wanted faked and named it (FakeItAttribute) and create a new attribute to enable discovery and creation of fake object for fields with that attribute:
NUnit has had the ability to execute code upon these events by decorating fixture classes and methods with the appropriate NUnit- provided attributes. Action Attributes allow the user to create custom attributes to encapsulate specific actions for use before or after any test is run.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class AutoFakeAttributeBase : Attribute, ITestAction { private readonly IFakeHelper _fakeHelper; protected AutoFakeAttributeBase(IFakeHelper fakeHelper) { _fakeHelper = fakeHelper; } private IEnumerable<FieldInfo> _testFields; public void BeforeTest(TestDetails details) { var isTestFixture = details.Method == null; if (isTestFixture) { DiscoverFieldsToFake(details); return; } foreach (var testField in _testFields) { var fakeObject = _fakeHelper.DynamicallyCreateFakeObject(testField.FieldType); testField.SetValue(details.Fixture, fakeObject); } } public void AfterTest(TestDetails details) { } private void DiscoverFieldsToFake(TestDetails details) { _testFields = details.Fixture.GetType() .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(testField => testField.CustomAttributes.Any(data => data.AttributeType == typeof(FakeItAttribute))); } public ActionTargets Targets { get { return ActionTargets.Test | ActionTargets.Suite; } } }I’ve inherited that attribute with AutoFakeItEasyAttribute that uses FakeItEasy and reflection to create fake objects.
[TestFixture, AutoFakeItEasy] public class UsingSimpleClassTests { [FakeIt] private IDependency _fakeDependency; // Not faked private IDependency _uninitializedDependency; [Test] public void FakesCreatedAutomatically() { Assert.That(_fakeDependency, Is.Not.Null); } [Test] public void FieldsWithoutAttributesAreNotInitialized() { Assert.That(_uninitializedDependency, Is.Null); } }Quite cool, and yes it’s on GitHub.
Labels: .NET, AutoFixture, C#, FakeItEasy, Mock objects, Unit tests