I have a method
Task<Document> GetCampaignById(Tenant tenant, string language, string campaignId);
that I am trying to mock:
mockLocator.Setup(l => l.GetCampaignById(
It.IsAny<Tenant>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns(Task.FromResult(dummy));
I did, at first have "not set up" output but I am not getting any at all now and the test just shows as failed. I have tried changing to ReturnsAsync(dummy) but that did not alter my output at all. moq is set to strict but I don't think that should matter.
As far as I can tell I am setting this up with the correct parameter types and the correct return type but the test seems to fail before it even starts. Can anyone shed any light on this?
Full Test
[TestCase(1)]
[TestCase(2)]
[TestCase(3)]
[TestCase(4)]
[TestCase(5)]
public async Task ShouldCallUpdaterForEveryTenantResolved(int tupleCount)
{
// Arrange
var tenantTuples = CreateTenantTuples(tupleCount);
var mockTenantResolver = MockRepository.Create<ITenantResolver>();
mockTenantResolver.Setup(tr => tr.GetTenantTuples(It.IsAny<string>()))
.Returns(tenantTuples);
var mockCampaignIngestionService = MockRepository.Create<ICampaignIngestionService>();
var dummy = new Document();
var mockLocator = MockRepository.Create<IVehicleSearchStockUpdater>();
mockLocator.Setup(l => l.GetCampaignById(
It.IsAny<Tenant>(),
It.IsAny<string>(),
It.IsAny<string>()))
.Returns(Task.FromResult(dummy));
mockLocator.Setup(l => l.UpsertNewStockLevel(
It.IsAny<Document>(),
It.IsAny<OmegaConnector.Functions.PartnerCommunicator.Models.ChangeStockInfo>()))
.Returns(Task.FromResult(dummy));
var sut = new CampaignIngestionProcessor(
mockTenantResolver.Object,
mockCampaignIngestionService.Object,
mockLocator.Object);
var data = GetSimpleTestData();
data.NewStock = 5;
// Act
await sut.SubmitChangeStock(data);
// Assert
mockLocator.Verify(l => l.GetCampaignById(
It.IsAny<Tenant>(),
It.IsAny<string>(),
It.IsAny<string>()),
Times.Exactly(tupleCount)
);
mockLocator.Verify(l => l.UpsertNewStockLevel(
It.IsAny<Document>(),
It.IsAny<OmegaConnector.Functions.PartnerCommunicator.Models.ChangeStockInfo>()),
Times.Exactly(tupleCount)
);
}
Related
im trying to write unit tests for a class that is written using reactivex.io .
my test code is something like this:
[TestMethod]
public void TestMethod1()
{
string userName = "Moeen";
string password = "moeen123";
string instrument = "Bass";
_loggerMock = new Mock<ILogger>();
_loggerMock.Setup(x => x.RequestInput(Messages.EnterUsername)).Returns(Observable.Return(userName));
_loggerMock.Setup(x => x.RequestInput(Messages.EnterPassword)).Returns(Observable.Return(password));
// _loggerMock.Setup(x => x.ShowProgressIndicator("loading")).Returns(ValueFunction);
var options = Enum.GetValues(typeof(Instrument)).Cast<Instrument>().Select(val => val.ToString());
_loggerMock.Setup(x => x.RequestInput($"{Messages.SelectInstrument} [{string.Join("|", options)}]")).Returns(Observable.Return(instrument));
_loggerMock.Setup(x => x.ShowMessage(""));
_backendMock = new UnreliableFakeBackend();
var result = new SignupFlow(_backendMock, _loggerMock.Object).Run();
result.Subscribe(x =>
{
Assert.AreEqual(true,false);
});
I tested it but the Assert code never gets called inside the subscribe function so the function always asserts true.
as I read the docs I have to write a scheduler to make it work but it doesn't explain well enough to make it work.
I have an interface definition where the method has an out parameter defined
public interface IRestCommunicationService
{
TResult PerformPost<TResult, TData>(string url, TData dataToSend, out StandardErrorResult errors);
}
I have the following class that is using the above interface
public TripCreateDispatchService(IRestCommunicationAuthService restCommunicationService, ISettings settings)
{
_restCommunicationService = restCommunicationService;
_settings = settings;
}
public FlightAlert CreateTrip(string consumerNumber, PostAlertModel tripModel, out StandardErrorResult apiErrors)
{
url = .. code ommited
var result = _restCommunicationService.PerformPost<FlightAlert, PostAlertModel>(url), tripModel, out apiErrors);
return result;
}
In my unit tests I am trying to verify that the PerformPost Method of the RestCommunication object is called.
But no matter what I do, I cannot get Moq to verify that the method was called
public void DispatchService_PerformPost()
{
var consumerNumber = ...
var trip = ...
var result = ...
var apiErrors = new StandardErrorResult();
... code to setup mock data
_mockRestCommunicationService = new Mock<IRestCommunicationAuthService>();
_mockEestCommunicationService.Setup(x => x.PerformPost<string, PostAlertModel>(It.IsAny<string>(), It.IsAny<PostAlertModel>(), out apiErrors)).Verifiable();
_systemUnderTest.CreateTrip(consumerNumber, trip, out apiErrors);
_mockRestCommunicationService.Verify(m =>
m.PerformPost<StandardErrorResult, PostAlertModel>(
It.IsAny<string>(),
It.IsAny<PostAlertModel>(), out apiErrors
), Times.Once);
}
But I am receiving the following error
Moq.MockException :
Expected invocation on the mock once, but was 0 times:
m => m.PerformPost<StandardErrorResult,PostAlertModel>(It.IsAny<String>(), It.IsAny<PostAlertModel>(), .apiErrors)
No setups configured.
How do I go about verifying that the method was called.
I am using Moq and NUnit
UPDATE 1
As per the comment from Sunny, I have modified the test to use a callback as follows
var consumerNumber = ...
var trip = ...
var result = ...
StandardErrorResult apiErrors;
_mockRestCommunicationService.Setup(x => x.PerformPost<string, PostAlertModel>(
It.IsAny<string>(), It.IsAny<PostAlertModel>(), out apiErrors))
.Callback<string, PostAlertModel, StandardErrorResult>
((s, m, e) => e.Errors = new System.Collections.Generic.List<StandardError>()
{
new StandardError { ErrorCode = "Code", ErrorMessage = "Message" }
});
_systemUnderTest.CreateTrip(consumerNumber, trip, out apiErrors);
Assert.That(apiErrors.Errors, Is.Not.Null);
This is the error that is now being thrown when executing the test.
System.ArgumentException : Invalid callback. Setup on method with
parameters (String,PostAlertModel,StandardErrorResult&)
cannot invoke callback with parameters (String,PostAlertModel,StandardErrorResult).
at Moq.MethodCall.ThrowParameterMismatch(ParameterInfo[] expected, ParameterInfo[] actual)
at Moq.MethodCall.SetCallbackWithArguments(Delegate callback)
at Moq.MethodCallReturn`2.Callback(Action`3 callback)
This error is thrown at the Setup statement.
FYI. I am using Resharper 8 and using their test runner to execute my tests.
If I try to add the out parameter to the callback, the code will not compile.
I get the same error if I modify the setup to
_mockRestCommunicationService.Setup(x => x.PerformPost<string, PostAlertModel>(
It.IsAny<string>(), It.IsAny<PostAlertModel>(), out apiErrors))
.Callback
((string s, PostAlertModel m, StandardErrorResult e) => e.Errors = new System.Collections.Generic.List<StandardError>()
{
new StandardError { ErrorCode = "Code", ErrorMessage = "Message" }
});
In the project I am working on we have used out It.Ref<T>.IsAny where T is the out parameter type (Moq version 4.14). This is because out is used as a parameter modifier, such that the value are passed by reference instead of by value.
In your case the verify method could look like this:
_mockRestCommunicationService.Verify(
_ => _.PerformPost<StandardErrorResult, PostAlertModel>(
It.IsAny<string>(),
It.IsAny<PostAlertModel>(),
out It.Ref<StandardErrorResult>.IsAny
),
Times.Once
);
To make sure no other unexpected invocations happened, you can also add:
_mockRestCommunicationService.VerifyNoOtherCalls()
It's better to actually use AAA and not verify the mock. Setup your method to return some specific result and assert that the result have been returned:
var myCommResult = new PostAlertModel();
_mockEestCommunicationService
.Setup(x => x.PerformPost<string, PostAlertModel>(It.IsAny<string>(), It.IsAny<PostAlertModel>(), out apiErrors)
.Returns(myCommResult);
var response = _systemUnderTest.CreateTrip(consumerNumber, trip, out apiErrors);
Assert.AreSame(myCommResult, response);
The above will validate that the method was called, based on the example code.
If for some reason, the code in the question is not really representative of the real code, and there is no way to assert on the return of the method, than you can use Callback instead, and put something in the errors so you can verify.
Something like:
_mockEestCommunicationService
.Setup(x => x.PerformPost<string, PostAlertModel>(It.IsAny<string>(), It.IsAny<PostAlertModel>(), out apiErrors))
.Callback( (string s, PostAlertModel m, StandardErrorResult e) => e.Add("Some error to test");
And later verify that apiErrors has the error you inserted in the callback.
How can I test the DeleteAppointmentById here?
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
_dataContextProvider is mocked with moq. If I run the test it never enters DeleteAppointmentById of course
The method to test:
public IEnumerable<uint> DeleteAppointment(uint appointmentId)
{
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
}
DeleteAppointmentById is the inner method (private) I am really interested in.
my test:
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Action<IDataAdapterRW>>()));
var calendarService = new CalendarService(dbContextMock.Object);
//Run
var result = calendarService.DeleteAppointment(1);
//Assert
Assert.AreEqual(1, result);
}
You can access the result of the Func passed as parameter in Run method, and to Assert the result like below.
Why to return the result? Because it's a mock and don't know how Run method is behaving.
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Func<IDataAdapterRW, IEnumerable<uint>>>()))
.Returns((Func<IDataAdapterRW, IEnumerable<uint>> func) => { return func(dataAdapterMock.Object);}); // configure the mock to return the list
var calendarService = new CalendarService(dbContextMock.Object);
//Run
int id = 1;
var result = calendarService.DeleteAppointment(id);
//Assert
var isInList = result.Contains(id); // verify the result if contains the
Assert.AreEqual(isInList, true);
}
Unit tests tend to take the following structure:
Arrange: set up the context. In this case, you'd probably create an appointment and save it to the database.
Act: call the unit you're testing. In this case, DeleteAppointmentById(db, appointment).
Assert: check if side effects and returns were correct. In this case, you may attempt to load this appointment from the database, and assert that you were unable (because it should have been deleted).
is it possible to assert whether a method has been called? I'm testing the following method and I want to assert that the _tokenManager.GetToken() has been called. I just want to know if the method has been called as the method does not return a value. I am using Moq.
Thanks,
Code snippet
public void Subscribe(string code, string emailAddress, string columnKey)
{
// Request authentication token
var token = _tokenManager.GetToken(code, false);
if (!_tokenValidator.Validate(token))
{
// Token has expired or invalid - refresh the token
token = _tokenManager.GetToken(code, true);
}
// Subscribe email
_silverpopRepository.Subscribe(token.AccessToken, emailAddress, columnKey);
}
You should mock TokenManager and TokenValidator, and then create two unit test cases:
Case 1: token is validated and GetToken is called exactly once
Case 2: token is not validated and GetToken is called exactly twice
Case 1:
[Test]
public void Subscribe_TokenIsValidated_GetTokenIsCalledOnce()
{
// Arrange:
var tokenManagerMock = Mock.Of<TokenManager>();
var tokenValidatorMock = Mock.Of<TokenValidator>(x =>
x.Validate(It.IsAny<Token>()) == true);
var subscriber = new Subscriber
{
TokenManager = tokenManagerMock,
TokenValidator = tokenValidatorMock
};
// Act:
subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>());
// Assert:
Mock.Get(tokenManagerMock).Verify(x =>
x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Once);
}
Case 2:
[Test]
public void Subscribe_TokenIsExpiredOrInvalid_GetTokenIsCalledTwice()
{
// Arrange:
var tokenManagerMock = Mock.Of<TokenManager>();
var tokenValidatorMock = Mock.Of<TokenValidator>(x =>
x.Validate(It.IsAny<Token>()) == false);
var subscriber = new Subscriber
{
TokenManager = tokenManagerMock,
TokenValidator = tokenValidatorMock
};
// Act:
subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(),
It.IsAny<string>());
// Assert:
Mock.Get(tokenManagerMock).Verify(x =>
x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Exactly(2));
}
Alternatively, you can create an unit test without mocking TokenValidator and verify if GetToken() has been called at least once. However, creating two cases as in the first example is preferred as we are testing all code paths.
// Arrange:
var tokenManagerMock = Mock.Of<TokenManager>();
var subscriber = new Subscriber {TokenManager = tokenManagerMock};
// Act:
subscriber.Subscribe(It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>());
// Assert:
Mock.Get(tokenManagerMock).Verify(x =>
x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.AtLeastOnce);
Read more about verification in Moq at:
Moq quick start at official website
Verifying the Number of Calls to a Mocked Method at BlackWasp
You can verify using MOQ using the Verify method. Like this:
var tokenManagerMock = new Mock<ITokenManager>();
var sut = new WhateverItIsCalled(tokenManagerMock.Object);
sut.Subscribe("ssss", "example#example.com", "XXX");
tokenManagerMock.Verify(m => m.GetToken(It.Is<string>(c => c == "ssss", It.Is<bool>(x => x == false)), Times.Once);
You need to be able to pass the token manager into your system under test somehow. Usually via the ctor or maybe a property.
I would suggest you use something like AutoFixture to remove the ugliness that is "ssss" and make things a bit more DRY.
You may need to make the token manager mock return something appropriate too that will pass the validation. Something like this:
var tokenManagerMock = new Mock<ITokenManager>();
tokenManagerMock.Setup(m => m.GetToken(It.Is<string>(x => x == "ssss", It.IsAny<bool>()).Returns("XXXXXX");
I have a ICreateService class that has dependency on ITicketApiAdapter. I've tried registering a mock ITicketAdaper so that it gets injected when I create an anonymous create service.
So, in setup, I have this register for the ticket adapter:
Fixture.Register(() =>
{
var ticketApiAdapter = new Mock<ITicketApiAdapter>();
ticketApiAdapter
.Setup( x => x.AddTicketComment(
It.IsAny<User>(),
It.IsAny<Customer>(),
It.IsAny<TicketComment>()))
.Returns(new SaveResult
{
Success = true,
Id = Fixture.CreateAnonymous<Guid>().ToString()
});
return ticketApiAdapter;
});
Fixture.Register(() => new CreateService(Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>().Object));
From my understanding, that should "freeze" both the ICreateService and Mock<ITicketApiAdapter> so that when I request an anonymous instance, it's the one I registered.
I have a test that looks like this:
[TestMethod]
public void CreateServiceCallsAddTicketComment()
{
var apiTicketAdapter = Fixture.CreateAnonymous<Mock<ITicketApiAdapter>>();
var createTicketRequest = Fixture.CreateAnonymous<CreateTicketComment>();
var createService = Fixture.CreateAnonymous<CreateService>();
var results = createService.CreateTicketComment(createTicketRequest);
apiTicketAdapter
.Verify(x => x.AddTicketComment(
It.IsAny<User>(),
It.IsAny<Customer>(),
It.IsAny<TicketComment>()),
Times.Once());
Assert.IsTrue(results.All(x => x.Success));
Assert.IsTrue(results.All(x => x.Errors.Count == 0));
}
I expect the apiTicketAdapter to be the one I registered so that I can verify the method is called. If I step through, the TicketApiAdapter is called, but Moq says it wasn't.
Edit
This is the error I get:
CreateServiceCallsAddTicketComment threw exception:
Moq.MockException: Expected invocation on the mock once, but was 0
times: x => x.AddTicketComment(It.IsAny(), It.IsAny(),
It.IsAny())
Configured setups: x => x.AddTicketComment(It.IsAny(),
It.IsAny(), It.IsAny()), Times.Never No
invocations performed.
When you Register a code block, that code block is going to be invoked every time the Fixture instance resolves the requested type. This means that it's not frozen. If you want to Freeze something, one of the Freeze overloads are often easier to use.
Better yet, since you seem to be using Moq, may I suggest using the AutoMoq extension?
That would enable you to rewrite the test to something like this:
[TestMethod]
public void CreateServiceCallsAddTicketComment(new AutoMoqCustomization());
{
var fixture = new Fixture().Customize()
var apiTicketAdapter = fixture.Freeze<Mock<ITicketApiAdapter>>();
ticketApiAdapter
.Setup( x => x.AddTicketComment(
It.IsAny<User>(),
It.IsAny<Customer>(),
It.IsAny<TicketComment>()))
.Returns(new SaveResult
{
Success = true,
Id = Fixture.CreateAnonymous<Guid>().ToString()
});
var createTicketRequest = fixture.Freeze<CreateTicketComment>();
var createService = fixture.CreateAnonymous<CreateService>();
var results = createService.CreateTicketComment(createTicketRequest);
apiTicketAdapter
.Verify(x => x.AddTicketComment(
It.IsAny<User>(),
It.IsAny<Customer>(),
It.IsAny<TicketComment>()),
Times.Once());
Assert.IsTrue(results.All(x => x.Success));
Assert.IsTrue(results.All(x => x.Errors.Count == 0));
}
That's assuming that CreateTicketRequest uses Constructor Injection or Property Injection.