I've read that when using moq you cannot mock a non-virtual function. I've also read that this should be possible now.. Is that true?
If so, then I'd like to mock the following query:
DatabaseContext.Database.ExecuteSqlCommand(updateQuery, newValue);
I'm overriding the Context in my test as so
DAL.Context.DatabaseContext = mockContext.Object;
I've tried this setup, but it seems the query stills goes agains my regular db
mockContext.Setup(c => c.Set<AppSalesAndResult>()).Returns(mockBudgetData.Object);
Any ideas, could perhaps the executesqlcommand be replaced with something else so that the row above would catch any udpates to the set? I use executesqlcommand due to performance reasons when updating multiple rows at once. Regular EF is too slow
UPDATE:
Reading the following post, How to Moq Entity Framework SqlQuery calls I wonder if a similar implementation would work for ExecuteSQLCommand...
What I have done to being able to Mock ExecuteSqlCommand, which is not possible to do in DataBase class, was to create the same method in my DbContext inheritance but this time virtual, and call the Database.ExecuteSqlCommand
public class MyDbContext : DbContext
{
public virtual int ExecuteSqlCommand(string sql, params object[] parameters)
{
return Database.ExecuteSqlCommand(sql, parameters);
}
public virtual int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters)
{
return Database.ExecuteSqlCommand(transactionalBehavior, sql, parameters);
}
Then I changed my business code to call this created method (Not Database method):
DatabaseContext.ExecuteSqlCommand(updateQuery, newValue);
Then, it works
It is possible to mock ExecuteSqlCommand. It is however not straightforward.
Being an extension method you have to mock the internals. It ends up creating a RawSqlCommand and invoking ExecuteNonQuery on an IRelationalCommand. It gets further complicated as the extension method creates new objects to do the actual work, as well as there being is no interface for RawSqlCommand or DatabaseFacade, you've got to mock the concrete classes.
I ended up writing EntityFrameworkCore.Testing as there isn't anything else around that can do all the mocks (FromSql, ExecuteSqlCommand, DbQuery, the relational stuff that the in-memory provider can't do). Save yourself some time as the mocks are involved, I certainly would have used an existing package if there was one when I was looking.
If you do want to roll your own the mock set up for ExecuteSqlCommand/ExecuteSqlCommandAsync looks like the following:
var relationalCommandMock = new Mock<IRelationalCommand>();
relationalCommandMock
.Setup(m => m.ExecuteNonQuery(It.IsAny<IRelationalConnection>(), It.IsAny<IReadOnlyDictionary<string, object>>()))
.Returns((IRelationalConnection providedConnection, IReadOnlyDictionary<string, object> providedParameterValues) => executeSqlCommandResult);
relationalCommandMock
.Setup(m => m.ExecuteNonQueryAsync(It.IsAny<IRelationalConnection>(), It.IsAny<IReadOnlyDictionary<string, object>>(), It.IsAny<CancellationToken>()))
.Returns((IRelationalConnection providedConnection, IReadOnlyDictionary<string, object> providedParameterValues, CancellationToken providedCancellationToken) => Task.FromResult(executeSqlCommandResult));
var relationalCommand = relationalCommandMock.Object;
var rawSqlCommandMock = new Mock<RawSqlCommand>(MockBehavior.Strict, relationalCommand, new Dictionary<string, object>());
rawSqlCommandMock.Setup(m => m.RelationalCommand).Returns(relationalCommand);
rawSqlCommandMock.Setup(m => m.ParameterValues).Returns(new Dictionary<string, object>());
var rawSqlCommand = rawSqlCommandMock.Object;
var rawSqlCommandBuilderMock = new Mock<IRawSqlCommandBuilder>();
rawSqlCommandBuilderMock
.Setup(m => m.Build(It.IsAny<string>(), It.IsAny<IEnumerable<object>>()))
.Returns((string providedSql, IEnumerable<object> providedParameters) => rawSqlCommand);
var rawSqlCommandBuilder = rawSqlCommandBuilderMock.Object;
var serviceProviderMock = new Mock<IServiceProvider>();
serviceProviderMock.Setup(m => m.GetService(It.Is<Type>(t => t == typeof(IConcurrencyDetector)))).Returns((Type providedType) => Mock.Of<IConcurrencyDetector>());
serviceProviderMock.Setup(m => m.GetService(It.Is<Type>(t => t == typeof(IRawSqlCommandBuilder)))).Returns((Type providedType) => rawSqlCommandBuilder);
serviceProviderMock.Setup(m => m.GetService(It.Is<Type>(t => t == typeof(IRelationalConnection)))).Returns((Type providedType) => Mock.Of<IRelationalConnection>());
var serviceProvider = serviceProviderMock.Object;
var databaseFacadeMock = new Mock<DatabaseFacade>(MockBehavior.Strict, mockedDbContext);
databaseFacadeMock.As<IInfrastructure<IServiceProvider>>().Setup(m => m.Instance).Returns(serviceProvider);
var databaseFacade = databaseFacadeMock.Object;
Mock.Get(mockedDbContext).Setup(m => m.Database).Returns(databaseFacade);
executeSqlCommandResult is the expected integer to return. You could use a callback to apply any operation said sql command performs on your data source.
Note that I am passing the mocked db context to the database facade mock constructor then performing another Moq set up on the mocked database, I get away with this as I have already performed a set up on the DbContext Database property as part of mocking the db context. I have observed test success with an inline new instance so I don't think it matters, just in my case I didn't want to spin up another instance.
Related
I'm trying to instantiate a class that handles a bunch of functionality, and is constructed using dependency injection. I mock two of my parameters, and the third is an in-memory database context. Now when asserting, it's throwing an error on the mockClientProxyParticipants.Verify() line:
System.NotSupportedException : Invalid verify on an extension method: proxy => proxy.SendAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>())
It is virtually impossible to not call the function, and calling Verify() with Times.Never() as parameter doesn't change anything.
I tried setting up the Linq argument of Verify() using normal strings like for mockClientProxyResults.Verify(), I tried using It.Is<string>(s => s == "some string") and I tried It.IsAny<string>().
I honestly don't understand what's wrong right now. Here's my test code, let me know if you want to see more:
var mockHub = new Mock<IHubContext<VoteHub>>();
var mockClients = new Mock<IHubClients>();
var mockClientProxyParticipants = new Mock<IClientProxy>();
var mockClientProxyResults = new Mock<IClientProxy>();
mockClients.Setup(clients => clients.Group("Participants")).Returns(mockClientProxyParticipants.Object);
mockClients.Setup(clients => clients.Group("Results")).Returns(mockClientProxyResults.Object);
mockHub.Setup(hub => hub.Clients).Returns(mockClients.Object);
var activeQuestionManagerMock = new Mock<IActiveQuestionManager>();
activeQuestionManagerMock.Setup(x => x.GetActiveQuestion())
.Returns(new ActiveQuestionModel(options));
QuestionHandler qm = new QuestionHandler(new VoteDbContext(options), mockHub.Object, activeQuestionManagerMock.Object);
//Act
qm.Ask(question);
//Assert
mockClientProxyParticipants.Verify(proxy => proxy.SendAsync(It.IsAny<string>(/*s => s == "AskQuestion"*/), It.IsAny<string>(/*s => s == qwaJSON*/), It.IsAny<CancellationToken>()), Times.Once());
mockClientProxyResults.Verify(proxy => proxy.SendAsync("UpdateCurrentQuestionProgress", It.IsAny<ActiveQuestionModel>(), default(CancellationToken)), Times.Once());
Turns out I misunderstood the error message and the issue is that IClientProxy.SendAsync() is an extension method, and Moq apparently doesn't like that. It's possible to use SendCoreAsync() instead, but you'll always have to pass an array as parameter, even if you want to send just one object or don't want to send any data at all.
credit to NKosi (see question comments)
I create a mock object with one method
IMyIterface dosGuard = Mock.Of<IMyIterface >(
dg =>
dg.IsMethod1(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>()) == false
);
I would like to specify the predicate for other method also :
dg.IsMethod2(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>()) == false
How can I do it for both methods together?
Yes, you actually can factory build the entire object's structure with Mock.Of<T>() -- it just appears a little quirky at first:
interface IInterface
{
int IntMethod();
string StringMethod();
}
var instance = Mock.Of<IInterface>(ifc =>
ifc.IntMethod() == 1 &&
ifc.StringMethod() == "Hello");
It uses boolean as MemberAssignment, but aside from that, it would read get me a Mock of IInterface, with an IntMethod returning 1 and a StringMethod returning "Hello". Also the It.IsAny<TType>() for parameters works in the predicate, as well as nested Mock.Of<T> calls.
Once you get going though, it becomes much cleaner, and one can spin up static methods for assignment/updating root test scenarios : i.e. take 'optimal' model and tweak a few fields, without having to re-type the entire model.
If you want to setup multiple things on your mock object you can't* use the Mock.Of<T> factory method, you need to setup the mock object yourself:
var dosGuardMock = new Mock<IMyInterface>();
dosGuardMock.Setup(dg => dg.IsMethod1(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>())).Returns(false);
dosGuardMock.Setup(dg => dg.IsMethod2(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>())).Returns(false);
var dosGuard = dosGuardMock.Object;
*Alternatively, you can use the factory method, and use the static Mock.Get method to modify the instance created by the factory method:
var dosGuard = new Mock.Of<IMyInterface>();
Mock.Get(dosGuard).Setup(dg => dg.IsMethod1(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>())).Returns(false);
Mock.Get(dosGuard).Setup(dg => dg.IsMethod2(It.IsAny<IPAddress>(), It.IsAny<string>(), It.IsAny<string>())).Returns(false);
However, I prefer the first example, because it draws an explicit difference between the Mock<T> instance and the "mock" T instance.
Is it possible to test for the following example if the Method1 called 1st, then Method2 called after and then Method3 by using the AAA syntax, in Rhino-mocks 3.6 ?
// Assert
var mock = MockRepository.GenerateMock<ISomeService>();
// Act
myObject.Service = mock;
// How should I change this part to ensure that Rhino Mocks check the call order as well?
mock.AssertWasCalled(m=>m.Method1());
mock.AssertWasCalled(m=>m.Method2());
mock.AssertWasCalled(m=>m.Method3());
Here's one way to do it...
mock.AssertWasCalled(m=>m.Method1(), options => options.WhenCalled(w => mockService.AssertWasNotCalled(x=>x.Method2())));
mock.AssertWasCalled(m=>m.Method2(), options => options.WhenCalled(w => mockService.AssertWasNotCalled(x=>x.Method3())));
mock.AssertWasCalled(m=>m.Method3());
You can, but you really shouldn't. You should focus on testing the externall observable behaviors, rather than the implementation.
Method call order can change without affecting the contract with the client of the API. In that case, your test will fail, even when it shouldn't.
In short, testing implementation leads to brittle tests. Brittle tests lead to abandonment of the tests. You don't want to go there.
Hope this helps.
Here is how to do it nicely.
var mocks = new MockRepository();
var fooMock = mocks.DynamicMock<IFoo>();
using (mocks.Ordered())
{
fooMock.Expect(x => x.Method1());
fooMock.Expect(x => x.Method2());
}
fooMock.Replay();
var bar = new Bar(fooMock);
bar.DoWork();
fooMock.VerifyAllExpectations();
Found the answer from this blog post: Verifying the Order Of Method Execution With Rhino Mocks 3.5 by Philip Japikse
Here's how to do it by building assertions into each method invocation.
// Arrange - Build the necessary assertions into the stubbed method invocations.
var mock = MockRepository.GenerateMock<ISomeService>();
mock.Stub(m => m.Method1()).WhenCalled(inv => mock.AssertWasNotCalled(m => m.Method2()));
mock.Stub(m => m.Method2()).WhenCalled(inv => mock.AssertWasNotCalled(m => m.Method3()));
// Act
myObject.Service = mock;
// Assert - Ensure each expected method was called.
mock.AssertWasCalled(m => m.Method1());
mock.AssertWasCalled(m => m.Method2());
mock.AssertWasCalled(m => m.Method3());
Since this is mixes up normal arrange-act-assert pattern by running assertions in mid-act, I like to include very specific error messages for these instances to identify test failures more easily.
mock.Stub(m => m.Method1()).WhenCalled(inv =>
mock.AssertWasNotCalled(m => m.Method2(), opt =>
opt.Message("Method2 cannot be called before Method1.")));
You could also achieve a similar result by saving the result of each invocation in a variable during the act step, and then checking the variable states during the assert step. This better preserves the division of the arrange-act-assert pattern, but it is more plumbing code to write and maintain.
// Arrange - Build the necessary state variables into the stubbed method invocations.
bool wasMethod1Called;
bool wasMethod2Called;
bool wasMethod2CalledBeforeMethod1;
bool wasMethod3CalledBeforeMethod2;
var mock = MockRepository.GenerateMock<ISomeService>();
mock.Stub(m => m.Method1()).WhenCalled(inv =>
{
wasMethod1Called = true;
});
mock.Stub(m => m.Method2()).WhenCalled(inv =>
{
wasMethod2Called = true;
wasMethod2CalledBeforeMethod1 = !wasMethod1Called;
});
mock.Stub(m => m.Method3()).WhenCalled(inv =>
{
wasMethod3CalledBeforeMethod2 = !wasMethod2Called;
});
// Act
myObject.Service = mock;
// Assert - Ensure each expected method was called, and that they were called in the right order.
mock.AssertWasCalled(m => m.Method1());
mock.AssertWasCalled(m => m.Method2());
mock.AssertWasCalled(m => m.Method3());
Assert.That(wasMethod2CalledBeforeMethod1, Is.False, "Method2 cannot be called before Method1.");
Assert.That(wasMethod3CalledBeforeMethod2, Is.False, "Method3 cannot be called before Method2.");
The mocks.Ordered() syntax specified by #craastad is the right way to do it, but I couldn't get it to work in RhinoMocks 3.5 - instead I had to tweak it to work without the instance of MockRepository that #craastad's solution used to call Ordered() on:
var fooMock = MockRepository.GenerateMock<IFoo>();
using (fooMock.GetMockRepository().Ordered())
{
fooMock.Expect(x => x.Method1());
fooMock.Expect(x => x.Method2());
}
var bar = new Bar(fooMock);
bar.DoWork();
fooMock.VerifyAllExpectations();
If you do it this way, it also appears to be unnecessary to call fooMock.Replay() either.
I'm struggeling with using moq and validating parameters passed to the methods of mocked interface. I have a code like:
MockRepository mockRepository = new MockRepository(MockBehavior.Default);
Mock<IConfigurationUpdater> workerInstanceMock = mockRepository.Create<IConfigurationUpdater>();
Mock<IConfiguration> configurationMock = mockRepository.Create<IConfiguration>();
configurationMock.Setup(t => t.Folder).Returns("Folder");
configurationMock.Setup(t => t.FileName).Returns("FileName");
workerInstanceMock
.Setup(
x => x.DoSomeWork(
It.Is<string>(
t => t == Path.Combine(configurationMock.Object.Folder, configurationMock.Object.FileName))))
.Verifiable("DoSomeWork not properly called");
mockRepository.VerifyAll();
The problem is that inside the lambda expresion generated for "It.Is", all properties of configurationMock (which were setup previously) are null. (if I would take that "Path.Combine" into a string, it would all work just fine).
In this exact case, the "Path.Combine" is failing because it received null parameters.
How should I properly use mocks and validate that my interface is called with the correct parameters.
Thanks,
florin
I think you need to use moq properties that will automatically start tracking its value (Stubs).
Instead of:
configurationMock.Setup(t => t.Folder).Returns("Folder");
configurationMock.Setup(t => t.FileName).Returns("FileName");
you can use
configurationMock.SetupProperty(t => t.Folder, "Folder");
configurationMock.SetupProperty(t => t.FileName, "FileName");
and then access the property as you did:
configurationMock.Object.Folder
More on moq properties can be found here: http://code.google.com/p/moq/wiki/QuickStart#Properties
public void SubmitMessagesToQueue_OneMessage_SubmitSuccessfully()
{
var messageServiceClientMock = new Mock<IMessageServiceClient>();
var queueableMessage = CreateSingleQueueableMessage();
var message = queueableMessage[0];
var xml = QueueableMessageAsXml(queueableMessage);
messageServiceClientMock.Setup(proxy => proxy.SubmitMessage(xml)).Verifiable();
//messageServiceClientMock.Setup(proxy => proxy.SubmitMessage(It.IsAny<XmlElement>())).Verifiable();
var serviceProxyFactoryStub = new Mock<IMessageServiceClientFactory>();
serviceProxyFactoryStub.Setup(proxyFactory => proxyFactory.CreateProxy()).Returns(essageServiceClientMock.Object);
var loggerStub = new Mock<ILogger>();
var client = new MessageClient(serviceProxyFactoryStub.Object, loggerStub.Object);
client.SubmitMessagesToQueue(new List<IMessageRequestDTO> {message});
//messageServiceClientMock.Verify(proxy => proxy.SubmitMessage(xml), Times.Once());
messageServiceClientMock.Verify();
}
I'm starting using Moq and struggling a bit.
I'm trying to verify that messageServiceClient is receiving the right parameter, which is an XmlElement, but I can't find any way to make it work. It works only when I don't check a particular value.
Any ideas?
Partial answer:
I've found a way to test that the xml sent to the proxy is correct, but I still don't think it's the right way to do it.
public void SubmitMessagesToQueue_OneMessage_SubmitSuccessfully()
{
var messageServiceClientMock = new Mock<IMessageServiceClient>();
messageServiceClientMock.Setup(proxy => proxy.SubmitMessage(It.IsAny<XmlElement>())).Verifiable();
var serviceProxyFactoryStub = new Mock<IMessageServiceClientFactory>();
serviceProxyFactoryStub.Setup(proxyFactory => proxyFactory.CreateProxy()).Returns(messageServiceClientMock.Object);
var loggerStub = new Mock<ILogger>();
var client = new MessageClient(serviceProxyFactoryStub.Object, loggerStub.Object);
var message = CreateMessage();
client.SubmitMessagesToQueue(new List<IMessageRequestDTO> {message});
messageServiceClientMock.Verify(proxy => proxy.SubmitMessage(It.Is<XmlElement>(xmlElement => XMLDeserializer<QueueableMessage>.Deserialize(xmlElement).Messages.Contains(message))), Times.Once());
}
By the way, how could I extract the expression from the Verify call?
If the verification logic is non-trivial, it will be messy to write a large lambda method (as your example shows). You could put all the test statements in a separate method, but I don't like to do this because it disrupts the flow of reading the test code.
Another option is to use a callback on the Setup call to store the value that was passed into the mocked method, and then write standard Assert methods to validate it. For example:
// Arrange
MyObject saveObject;
mock.Setup(c => c.Method(It.IsAny<int>(), It.IsAny<MyObject>()))
.Callback<int, MyObject>((i, obj) => saveObject = obj)
.Returns("xyzzy");
// Act
// ...
// Assert
// Verify Method was called once only
mock.Verify(c => c.Method(It.IsAny<int>(), It.IsAny<MyObject>()), Times.Once());
// Assert about saveObject
Assert.That(saveObject.TheProperty, Is.EqualTo(2));
I've been verifying calls in the same manner - I believe it is the right way to do it.
mockSomething.Verify(ms => ms.Method(
It.IsAny<int>(),
It.Is<MyObject>(mo => mo.Id == 5 && mo.description == "test")
), Times.Once());
If your lambda expression becomes unwieldy, you could create a function that takes MyObject as input and outputs true/false...
mockSomething.Verify(ms => ms.Method(
It.IsAny<int>(),
It.Is<MyObject>(mo => MyObjectFunc(mo))
), Times.Once());
private bool MyObjectFunc(MyObject myObject)
{
return myObject.Id == 5 && myObject.description == "test";
}
Also, be aware of a bug with Mock where the error message states that the method was called multiple times when it wasn't called at all. They might have fixed it by now - but if you see that message you might consider verifying that the method was actually called.
EDIT: Here is an example of calling verify multiple times for those scenarios where you want to verify that you call a function for each object in a list (for example).
foreach (var item in myList)
mockRepository.Verify(mr => mr.Update(
It.Is<MyObject>(i => i.Id == item.Id && i.LastUpdated == item.LastUpdated),
Times.Once());
Same approach for setup...
foreach (var item in myList) {
var stuff = ... // some result specific to the item
this.mockRepository
.Setup(mr => mr.GetStuff(item.itemId))
.Returns(stuff);
}
So each time GetStuff is called for that itemId, it will return stuff specific to that item. Alternatively, you could use a function that takes itemId as input and returns stuff.
this.mockRepository
.Setup(mr => mr.GetStuff(It.IsAny<int>()))
.Returns((int id) => SomeFunctionThatReturnsStuff(id));
One other method I saw on a blog some time back (Phil Haack perhaps?) had setup returning from some kind of dequeue object - each time the function was called it would pull an item from a queue.
A simpler way would be to do:
ObjectA.Verify(
a => a.Execute(
It.Is<Params>(p => p.Id == 7)
)
);
I believe that the problem in the fact that Moq will check for equality. And, since XmlElement does not override Equals, it's implementation will check for reference equality.
Can't you use a custom object, so you can override equals?
Had one of these as well, but the parameter of the action was an interface with no public properties. Ended up using It.Is() with a seperate method and within this method had to do some mocking of the interface
public interface IQuery
{
IQuery SetSomeFields(string info);
}
void DoSomeQuerying(Action<IQuery> queryThing);
mockedObject.Setup(m => m.DoSomeQuerying(It.Is<Action<IQuery>>(q => MyCheckingMethod(q)));
private bool MyCheckingMethod(Action<IQuery> queryAction)
{
var mockQuery = new Mock<IQuery>();
mockQuery.Setup(m => m.SetSomeFields(It.Is<string>(s => s.MeetsSomeCondition())
queryAction.Invoke(mockQuery.Object);
mockQuery.Verify(m => m.SetSomeFields(It.Is<string>(s => s.MeetsSomeCondition(), Times.Once)
return true
}