I am testing a method which will call another method if certain parameters are certain values and not if they are other.
I was using Moq's Verify to test this. However when I use the xUnit to see if the method is not called when sending parameters with data which should not make the method call the 2nd method.
Problem is that I cannot do
mockObject.Verify();
Assert.Throws<Moq.MockVerificationException>(()=>mockObject.Method());
I changed from MSTest to xUnit because the support for throws was built in and I had to have the ExpectedException attribute decorating my test method before.
I tried to cast the Moq non-public exception to the public parent Moq.MoqException but that will throw an error.
so I think I may have to do:
try {moqObj.Verify();}
catch(Moq.Exception mve)
{
Assert.SomethingIsException();
}
As I understand, you're just trying to verify whether certain methods are called or not? If so, try this:
var theThing = new Mock<IThing> ();
theThing.Verify (x => x.DoSomething ("a"), Times.Never);
theThing.Verify (x => x.DoSomething ("b"), Times.Once);
If you need to invoke another method after the first method is called, you could use a callback:
theThing.Setup (x => x.DoSomething ("a")).Callback (() => {});
Related
I'd like to explore wether we can save time by setting that all Moq-mocks created by AutoMoq should by default return Fixture-created values as method return values.
This would be beneficial when doing a test like the following:
[TestMethod]
public void Client_Search_SendsRestRequest()
var client = fixture.Create<Client>();
// Could be removed by implementing the mentioned functionality
Mock.Of(JsonGenerator).Setup(j => j.Search(It.IsAny<string>())).Returns(create("JsonBody")));
client.Search(fixture.Create("query"));
Mock.Of(client.RestClient).Verify(c => c.Execute(It.IsAny<RestRequest>()));
Mock.Of(client.RestClient).Verify(c => c.Execute(It.Is<RestRequest>(r => record(r.Body) == record(client.JsonGenerator.Search(query)))));
}
Note that the generated values must be cached inside (?) the proxies, we want the same value "frozen" in order to check. Also, setting up the mock with Setup should override the created value.
So, how can we modify AutoMoq mocks to do this?
A simple test verifying that it works could be:
[TestMethod]
public void MockMethodsShouldReturnCreatedValues()
{
Guid.Parse(new Fixture().Create<ITest>().Test());
}
public interface ITest
{
string Test();
}
Definitely possible, just use the AutoConfiguredMoqCustomization instead of the AutoMoqCustomization. The mocks will use the fixture to generate returns values for all its methods, properties and indexers (*).
Properties will be evaluated eagerly, whereas indexers/methods' return values will be evaluated and cached when invoked for this first time.
(*) There are two exceptions to this rule - the customization cannot automatically setup generic methods or methods with ref parameters, as explained here. You'll have to set those up manually, with the help of the .ReturnsUsingFixture method.
While trying to write some unit tests with Moq and MVVM Light's messenger class I've encountered an issue. The issue is how can you Mock<IMessenger>(); and verify that a message was received and the action processed?
What is the correct way write the test if using IMessenger? I've seen plenty of examples using Messenger.Default,
and having Messenger.Reset() in the TestInitialize method. I used IMessenger believing it would help with test-ability.
Using Moq to verify that a message is sent works as I would expect.
[TestMethod]
public void LoadData_SendsUpdateStatusEvents()
{
//Arrange
_mockMessenger.Setup(x => x.Send(It.IsAny<string>(),
It.IsAny<UpdateStatusEvent>()));
//Act
//Assert
_mockMessenger.Verify(x => x.Send(It.IsAny<string>(),
It.IsAny<UpdateStatusEvent>()), Times.Exactly(2));
}
However, if I have this registration in my constructor..
_messenger.Register<IUnitsManager>(this, OnUpdatedUnitsEvent);
And I write a unit test to check that OnUpdatedUnitsEvent runs...
[TestMethod]
public void OnUpdatedUnitsEvent_UpdateUserUnitValueOfAllMaterials()
{
//Arrange
_mockUnits.Object.SetUnitsToMetric();
_mockMessenger.Object.Send(_mockUnits.Object);
//Act
var currentItem = _materialMasterVm.MaterialModels.CurrentItem as MaterialDetailViewModel;
//Assert
Assert.AreEqual(DensitySolidSymbols.KgCm3, currentItem.Density.UserUnitType);
Assert.AreEqual(PressureSymbols.KPa, currentItem.YieldStress);
Assert.AreEqual(PressureSymbols.KPa, currentItem.YoungsModulus);
}
What is the recommended approach to get this to work using when using IMessenger and Moq?
Here's what I would do:
// This is a field in your test fixture
Action<IUnitsManager> _callback;
...
// In your test setup, save the delegate that is registered with the message type
mockMessenger.Setup(x => x.Register(It.IsAny<object>(), It.IsAny<Action<IUnitsManager>>()))
.Callback<object, Action<IUnitsManager>>((o, a) => _callback = a);
...
// When you want to send the message, invoke the callback
_callback(_mockUnits.Object);
However, I want to add that when sending messages in tests using the IMessenger, I do not mock it. The above is a little too much hassle to setup, and besides, this is exactly what the Messenger concrete does anyways. To put it another way, I'm either putting my faith in Moq's Setup/Callback mechanism or in the MVVM Light Messenger's Register/Send mechanism. I choose the latter because I don't need to do any extra setup in my tests to make it work.
So, when I need to test that my SUT registers for and handles messages properly, I assume the IMessenger works as expected and just use a concrete instance, i.e.:
// Create a new messenger every test
IMessenger mockMessenger = new Messenger();
// Send the message
mockMessenger.Send<IUnitsManager>(_mockUnits.Object);
I am setting up a Mock as shown below. It is passed into the constructor of the target. The target has a Decrypt method that is called twice within the lifetime of the target. Each time the Decrypt method is called, it Disposes of the certificate that is "newed" up in the Setup. However, when calling the Decrypt object the second time, I am getting an ObjectDisposed method upon attempting the decryption. If I replace this Mock with a Fake implementation of ICertificateHelperAdapter that calls GetCertificate(), then the second call to Decrypt works properly.
I am deducing that when I use the Mock, it is not returning me a new instance of the object on subsequent calls to GetCertificate. Is this by design?
private Mock<ICertificateHelperAdapter> GetCertificateHelperAdapter()
{
Mock<ICertificateHelperAdapter> certificateHelper = new Mock<ICertificateHelperAdapter>();
certificateHelper.Setup(
ch => ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>())).Returns(this.GetCertificate()).Verifiable();
return certificateHelper;
}
private X509Certificate2 GetCertificate()
{
return new X509Certificate2(Environment.CurrentDirectory + "\\" + "azureconfig.pfx", "dingos");
}
The different overloads of Returns<T> behaves differently:
The one with T Returns<T>(T value) what you are using is always returning the same instance.
But there is a lazy version which uses Func<T>. They are looks like T Returns<T>(Func<T> value) and they will evaluate each time the parameter function when the setup method is called.
Sample from the Moq site:
// lazy evaluating return value
mock.Setup(foo => foo.GetCount()).Returns(() => count);
Change your setup to:
certificateHelper.Setup(ch =>
ch.GetCertificate(CertStoreName.My, StoreLocation.LocalMachine, It.IsAny<string>()))
.Returns(() => this.GetCertificate()).Verifiable(); //note the lambda in Returns
And it will call your GetCertificate() twice.
Is there an equivalent of the Rhino Mocks .Do() method in Moq? I am converting my Rhino Mocks code to Moq, and am stuck on the following:
mockedObject
.Expect(x => x.GetSomething())
.Do((Func<SomeClass>)(() => new SomeClass());
This is not the same as (in Moq, similar in Rhino Mocks):
mockedObject
.Setup(x => x.GetSomething())
.Return(new SomeClass());
When GetSomething() is called multiple times in your unit test, the first piece of code will always return a new instance. The second piece will always return the same instance.
What I want is for my mocked object (with Moq) to always return a new instance. So I actually want to provide an implementation of the GetSomething() method to my mocked object.
Using sequences won't do the trick, because I don't know how many times GetSomething() will be called, nor am I interested in this.
You should be able to pass .Returns a Func<SomeClass> just like you're doing with Rhino mocks:
mockedObject
.Setup(x => x.GetSomething())
.Returns(() => new SomeClass());
Seems like Moq is caching data I set up as return. When I do this:
var service = new Mock<AlbumService>();
service.Setup(x => x.CreateOne()).Returns(new AlbumService().CreateOne());
it returns the same object even thought AlbumService.CreateOne() returns new Album instance.
Is it possible to make Moq call the Returns Action every time I access CreateOne() ?
This ought to help:
var service = new Mock<AlbumService>();
service.Setup(x => x.CreateOne()).Returns(() => new AlbumService().CreateOne());
To elaborate, the Returns method accepts an object of the return type or a delegate that will evaluate to the return type. The delegate is invoked whenever the mocked method is invoked.