Why does this MustHaveHappened call on a FakeItEasy object fail in MSpec? - c#

When running following test all the assertions fail. Can't figure out why they fail, because the actual implementation does have a call to the objects.
Is this a known bug? Because some other tests do succeed.
[Subject("Pst Cleanup")]
public class When_running_Pst_CleanUp
{
Establish context = () =>
{
_folders = A.Fake<IOutlookFolderParameters>();
_processor = A.Fake<IOutlookPstCleaner>();
};
Because of = () => _processor.Cleanup(_folders);
It should_cleanup_the_mail_folder = () => A.CallTo(() => _folders.EmailFolder).MustHaveHappened();
It should_cleanup_tasks_folder = () => A.CallTo(() => _folders.TaskFolder).MustHaveHappened();
It should_cleanup_appointments_folder = () => A.CallTo(() => _folders.AppointmentFolder).MustHaveHappened();
private static IOutlookPstCleaner _processor;
private static IOutlookFolderParameters _folders;
}
Assertion failed for the following call: Outlook.Contracts.IOutlookFolderParameters.get_NotificationsFolder() Expected to find it at least once but no calls were made to the fake object.
at FakeItEasy.Core.FakeAsserter.AssertWasCalled(Func2 callPredicate, String callDescription, Func2 repeatPredicate, String repeatDescription) at FakeItEasy.Configuration.RuleBuilder.MustHaveHappened(Repeated repeatConstraint) at UnitTests.When_running_Pst_CleanUp.<.ctor>b__2() in When_running_Pst_CleanUp.cs: line 19

This is absolutely correct behavior of FakeItEasy. You need to use the real implementation for IOutlookPstCleaner to make your test succeed. Always make sure that you fake the correct things and don't fake your SUT accidentally.
With testing for the properties just being called you test absolutely nothing valuable. I could as well just write this implementation for IOutlookPstCleanerand your test would succeed:
public class Cleaner : IOutlookPstCleaner
{
public void Cleanup(IOutlookFolderParameters folders)
{
var email = folders.EmailFolder;
var task = folders.TaskFolder;
var appointment = folders.AppointmentFolder;
}
}
If you post your implementation of IOutlookPstCleaner I'm happy to help you find the right things to test.

Related

How do I mock PolicyResult to contain a value for FinalException?

I have created an abstract class that implements Polly that I want to write unit tests for.
In one of my tests I want to test how my method handles certain values of PolicyResult.FinalException.
Because the returned PolicyResult is null I get a NullReferenceException when evaluating result.FinalException
How do I mock the returned result?
What I have so far:
public class AbstractRestClientTest
{
private AbstractRestClient _sut;
private Mock<IRestRequestFactory> _requestFactoryMock;
private Mock<IRestClientFactory> _restClientfactoryMock;
private Mock<IPollyPolicyFactory> _policyFactoryMock;
private Mock<IAsyncPolicy> _policyMock;
private const string DUMMY_URL = "http://dosomething.com/getmesomething";
[SetUp]
public void SetUp()
{
_requestFactoryMock = new Mock<IRestRequestFactory>();
_restClientfactoryMock = new Mock<IRestClientFactory>();
_policyFactoryMock = new Mock<IPollyPolicyFactory>();
var settings = new MockSettings();
_policyMock = new Mock<IAsyncPolicy>();
_policyFactoryMock.Setup(mock =>
mock.CreateAsyncResiliencePolicy(settings))
.Returns(_policyMock.Object);
_sut = new MockRestClient(settings, _restClientfactoryMock.Object,
_policyFactoryMock.Object,
_requestFactoryMock.Object);
}
}
public class MockRestClient : AbstractRestClient
{
public MockRestClient(RestSettings settings, IRestClientFactory restClientFactory, IPollyPolicyFactory pollyPolicyFactory,
IRestRequestFactory requestFactory) : base(settings, restClientFactory, pollyPolicyFactory, requestFactory) {
}
}
public class MockSettings : RestSettings
{
public override string Naam => "TestSettings";
}
------------------ EDIT 1 --------------------------------
With Nkosi's comment I got a little bit further but still PolicyResult returned by _policy.ExecuteAndCaptureAsync is null. This leads me to believe that there is something wrong in the way that I mock that method.
I changed my test to the following but still it returns `null``:
[Test]
public async Task HandleRequest_IfFinalExceptionNotNull_ThenThrowsException()
{
var mockResult = new Mock<IRestResponse<int>>();
PolicyResult<IRestResponse<int>> result = PolicyResult<IRestResponse<int>>.Failure(mockResult.Object, new Context());
//Is the following mock correctly setup?
_policyMock.Setup(mock => mock.ExecuteAndCaptureAsync(It.IsAny<Func<Task<IRestResponse<int>>>>()))
.ReturnsAsync(result);
var url = new Url(DUMMY_URL);
Assert.ThrowsAsync<Exception>(() => _sut.GetResult<int>(url));
}
I evaluated the parameters needed for ExecuteAndCapture and changed my setup for this method accordingly, what am I doing wrong?
Based on the publicly available source code on GitHub, there really is no need to mock that class. While it does have an internal constructor, static factory methods exist that should allow for the creation of your desired instance
For example
Context context = //...created as needed
PolicyResult<TestResponse> result = PolicyResult<TestResponse>.Failure(..., context);
Choose the right combination to satisfy the expected result in your test.
The issue was I was mocking the wrong version of ExecuteAndCaptureAsync, I needed to mock the method with the following signature:
`Task<PolicyResult> ExecuteAndCaptureAsync(Func<CancellationToken, Task> action, CancellationToken cancellationToken);`
So after I changes my SetUp accordingly the test succeeded:
[Test]
public async Task HandleRequest_IfFinalExceptionNotNull_ThenThrowsException()
{
var mockResult = new Mock<IRestResponse<int>>();
PolicyResult<IRestResponse<int>> result = PolicyResult<IRestResponse<int>>.Failure(mockResult.Object, new Context());
_policyMock.Setup(mock => mock.ExecuteAndCaptureAsync(
It.IsAny<Func<CancellationToken, Task<IRestResponse<int>>>>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(result);
var url = new Url(DUMMY_URL);
Assert.ThrowsAsync<Exception>(() => _sut.GetResultaat(url, new CancellationToken()));
}

Moq - How to setup a Lazy interface

I want to mock a Lazy Interface and also Setup a method to return false.
The problem is, when i run the test, I get a NotSupportedException:
System.NotSupportedException: 'Invalid setup on a non-virtual (overridable in VB) member: mock => mock.Value
Here is a simplified example:
[TestMethod]
public void SomeTestMethod()
{
var someService = new Mock<Lazy<IService>>();
/*this line throws the exception*/
someService.Setup(x => x.Value.SomeMethod()).Returns(false);
...
}
Please consider that SomeMethod is actually virtual, but somehow getting the lazy initialization using x.Value is not supported by Moq.
I didn't found a solution for this specific scenario but I did view some other approaches on declarations, but sadly didn't work for me.
[TestMethod]
public void SomeTestMethod()
{
var someService = new Mock<IService>();
var lazySomeService = new Lazy<IService>(() => someService.Object);
//tried this but won't compile
//lazySomeService.Setup(x => x.Value.SomeMethod()).Returns(false);
//lazySomeService.Value.Setup(x => x.SomeMethod()).Returns(false);
...
}
You started on the right track with
var someService = new Mock<IService>();
var lazySomeService = new Lazy<IService>(() => someService.Object);
but the setup needs to be on the mock not the actual Lazy implementation.
someService.Setup(x => x.SomeMethod()).Returns(false);
That way when the Lazy.Value is called, it will be using the mock.

Exception of invocation on the mock was 0 times, but I can see performed invocations correctly

Here's my simplified version of unit test
var service = Fixture.Freeze<IService>();
var outerService = Fixture.Create<OuterService>();
var testObject = Fixture.Create<TestObject>();
outerService.Notify(testObject);
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
Note that:
outerService.Notify(testObject)
internally calls
IService.SendNotification(string testObject.Name, testObject, extraObject = null)
The above will cause the test to fail, complaining that:
Expected invocation 1 time,but was 0 times:
s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null)
No setups configured.
Performed invocations:
IService.SendNotification("testObject", UnitTest.TestObject, null)
I don't understand, the performed invocation looks exactly like the expected invocation, what is going on here?
EDIT
Ok so it is working if I call service.SendNotification directly in the test, but it won't work if I call it via outerService? Why?
UPDATE
Apologies if my question was not clear enough, here's some more details as to how the Fixture object is configured:
Fixture fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
fixture.Customize(new SpecimenCustomization());
That is really about it for the details, it's hopefully not a complicated scenario I suppose.
That error occurs when you call Mock.Get and The received mocked instance was not created by Moq. That means that there were No setups configured for the mocked service.
Given this simplified assumption.
public class OuterService {
private IService service;
public OuterService(IService service) {
this.service = service;
}
public void Notify(TestObject testObject) {
service.SendNotification(testObject.Name, testObject, extraObject: null);
}
}
public interface IService {
void SendNotification(string name, TestObject testObject, object extraObject);
}
public class TestObject {
public string Name { get; set; }
}
The following test should work
//Arrange
var service = Mock.Of<IService>();
var outerService = new OuterService(service);
var testObject = new TestObject { Name = "testObject" };
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
Moq is now aware of the service object and can extract the mock setup from the mocked instance created above.
Update:
Realized you were using AutoFixture and after some research was able to recreate your problem. You need to customize AutoFixture to use Moq.
Check Auto-Mocking with Moq on how to do that.
The following then worked given the same assumptions stated above.
//Arrange
var fixture = new Fixture();
fixture.Customize(new Ploeh.AutoFixture.AutoMoq.AutoMoqCustomization());
var service = fixture.Freeze<IService>();
var outerService = fixture.Create<OuterService>();
var testObject = fixture.Create<TestObject>();
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);

C# Rhino.Mocks - How do I write test code without repeating myself?

I wish to stub all dependencies out in my Rhino.Mocks unit tests, but I end up repeating myself. As the number of dependencies keeps increasing, I need to revisit my existing unit tests and need to add the dependencies. It's unsatisfying and also a signal that I should be doing it in another way.
If I just move initialization to a separate method, I pass into it all the mocks and I have achieved nothing.
Is there a way to initialize and then pass the Using(mocks.Record) into a method as a lambda expression? Or how do you do it?!
Thanks in advance for any comments,
Anders, Denmark
[Test, Category("UnitTest")]
public void TestThatApplicationCanExitByDefault()
{
var mocks = new MockRepository();
var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
var versionProvider = mocks.StrictMock<IVersionProvider>();
var eventAggregator = mocks.StrictMock<IEventAggregator>();
var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
var stateManager = mocks.StrictMock<IStateManager>();
var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();
using (mocks.Record())
{
// constructor fires:
eventAggregator
.Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
.Return(currentWorkspaceChangedEvent);
currentWorkspaceChangedEvent
.Stub(x => x.Subscribe(null))
.IgnoreArguments();
}
var target = new MainWindowViewModel(
workspaceViewModelProvider,
workspaceRepository,
userResponseProvider,
versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);
var canAppExit = target.CanAppExit();
Assert.IsTrue(canAppExit);
mocks.VerifyAll();
}
[Test, Category("UnitTest")]
public void TestThatInsertProjectWorks()
{
var mocks = new MockRepository();
var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
var versionProvider = mocks.StrictMock<IVersionProvider>();
var eventAggregator = mocks.StrictMock<IEventAggregator>();
var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
var stateManager = mocks.StrictMock<IStateManager>();
var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();
var workspaceViewModel = mocks.StrictMock<IWorkspaceViewModel>();
using (mocks.Record())
{
// constructor fires:
eventAggregator
.Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
.Return(currentWorkspaceChangedEvent);
currentWorkspaceChangedEvent
.Stub(x => x.Subscribe(null))
.IgnoreArguments();
workspaceViewModelProvider
.Stub(x => x.GetViewModel())
.Return(workspaceViewModel);
workspaceViewModel
.Stub(x => x.InsertProject());
}
var target = new MainWindowViewModel(
workspaceViewModelProvider,
workspaceRepository,
userResponseProvider,
versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);
target.InsertProject();
mocks.VerifyAll();
}
I tend to have a helper method which is responsible for building my mocks, and this method takes a lambda. The lambda can then communicate the mocks to a test. I have overloads of the test helper method to form an API and thus restrict what mocks are available to the test. In this way mock building can be centralized and so minimize dependency tramping across your tests.
It's more obvious with an example. This uses Moq, but the technique is general.
private static void RunTest(Action<IThing1> test)
{
RunTest(test: (thing1, thing2, thing3) => test(thing1));
}
private static void RunTest(Action<IThing1, IThing2> test)
{
RunTest(test: (thing1, thing2, thing3) => test(thing1, thing2));
}
private static void RunTest(Action<IThing1, IThing2, IThing3> test)
{
IThing1 thing1 = new Mock<IThing1>().Object;
IThing2 thing2 = new Mock<IThing2>().Object;
IThing3 thing3 = new Mock<IThing3>().Object;
test(thing1, thing2, thing3);
}
[Test]
public void do_some_stuff_to_a_thing()
{
RunTest(test: thing1 => {
//Do some testing....
});
}
[Test]
public void do_some_stuff_to_things()
{
RunTest(test: (thing1, thing2) => {
//Do some testing....
});
}
Try using a base class with protected mocked objects and use [SetUp]/[TestFixtureSetUp] (with NUnit for example).
It is wise to put only common objects with initialization to base class - use [SetUp]/[TestFixtureSetUp] in the same class where there are multiple unit tests and you need to mock/initialize something specific only to this tests. Putting everything in your base bloats your unit tests as well (at least they execute longer).

Unit Testing With Computer Owned States

I am writing a unit test for when my computer receives/makes a phone call.
The methods being tested are the events that handle the incoming/outgoing call. If the caller is not an approved caller then the call is rejected.
The code works fine, but I can't really find anything to test against for my unit test. The problem is that the actual state of "if my computer is in a call or not" is not controlled my by class. Only the computer knows if a call is currently connected or not.
I am hoping that there are some Unit Test Guru's out there than can tell me what to do to test this scenario. I do not want to create a dummy var that has no relation to my code just to make my unit test pass.
To make this a bit more concrete here is my unit test:
private DeviceMediator deviceMediator;
private IDeviceControlForm deviceControlForm;
private IDataAccess data;
private ICallMonitor callMonitor;
// Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
deviceControlForm = MockRepository.GenerateStub<IDeviceControlForm>();
data = MockRepository.GenerateStub<IDataAccess>();
callMonitor = MockRepository.GenerateStub<ICallMonitor>();
deviceMediator = new DeviceMediator(deviceControlForm, data)
{CallMonitor = callMonitor};
}
[TestMethod]
public void TestHandleIncomingCall()
{
//Arrange
//Act
deviceMediator.OnIncomingCall(null, new CallState(),
new CallInfoState());
//Assert
// I could not find anything to feasably test on this.
Assert.IsTrue(true);
}
and here is the method it is calling:
public void OnIncomingCall(Call call, CallState callState,
CallInfoState callInfoState)
{
// See if this call is on our list of approved callers
bool callApproved = false;
foreach (PhoneContact phoneContact in Whitelist)
{
if (phoneContact.PhoneNumber == call.CallerID)
callApproved = true;
}
// If this is not an approved call then
if (!callApproved)
CallMonitor.Hangup();
}
Turns out I just did not know enough about Rhino Mocks. The answer to this issue can be found here.
This is my code with that answer incorporated.
Unit Test:
[TestMethod]
public void TestHandleIncomingCall()
{
//Arrange
callMonitor.InCall = true;
// This is the magic. When Hangup is called I am able to set
// the stub's InCall value to false.
callMonitor.Expect(x => x.Hangup()).Callback(() => WhenCalled(invocation =>
{
callMonitor.InCall = false;
});
List<PhoneContact> whiteList = FillTestObjects.GetSingleEntryWhiteList();
data.Expect(x => x.GetWhiteListData()).Return(whiteList);
const string invalidPhoneNumber = "123";
//Act
deviceMediator.HandleIncomingCall(invalidPhoneNumber);
//Assert
Assert.IsFalse(callMonitor.InCall);
}
I had to change my code to this because Call has an internal constructor:
public void OnIncomingCall(Call call, CallState callState,
CallInfoState callInfoState)
{
// See if this call is on our list of approved callers
HandleIncomingCall(call.CallerID);
}
public void HandleIncomingCall(string callNumber)
{
bool callApproved = false;
foreach (PhoneContact phoneContact in Whitelist)
{
if (phoneContact.PhoneNumber == callNumber)
callApproved = true;
}
// If this is not an approved call then
if (!callApproved)
CallMonitor.Hangup();
}
It's called dependancy injection. You make your code act on an interface that mimics the real Phone api, and supply your own controllable implementation for the tests. There are systems out there like Spring.Net that make this easier to do.
Here's a couple things you could do:
You could create a mock WhiteList collection that will contain a certain set of the PhoneContacts, and then call OnIncomingCall with PhoneContacts that are or are not in the WhiteList and then check the CallMonitor (or the Call object itself, I suppose) to see if the call is in the correct state. So Assert.IsTrue(call.IsConnected) or Assert.IsFalse(call.IsConnected) depending on the scenario you're testing.
You could also see if the method handles Call objects that are null or that are not in the correct state at the point where this method is being called.

Categories