Subsequent calls to a Mock.Setup result in the same object instance - moq

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.

Related

Mock.Verify does not identify call made to mock service provided by IServiceProvider

I'm trying to write an integration test for a service method. The test compiles and runs without error, but it says that the number of calls that match the predicate are 0.
Test setup:
[TestCase]
public void Save_Submission_Processing_And_ClientGroupMapping_Type()
{
Mock<ISubmissionRepository> submissionRepositoryMock = new Mock<ISubmissionRepository>();
submissionRepositoryMock.Setup(x => x.GetOne(It.IsAny<Guid>())).Returns(QueryResult<Submission>.Ok(new Submission()));
IServiceCollection services = new ServiceCollection();
services.AddSingleton(x => submissionRepositoryMock.Object);
ClientGroupMappingService clientGroupMappingService = new ClientGroupMappingService(services.BuildServiceProvider());
clientGroupMappingService.ProcessClientGroupMappingImport(Guid.NewGuid());
submissionRepositoryMock.Verify(c => c.Save(It.Is<Submission>(d => d.SubmissionStatus == SubmissionStatus.Processing)), Times.Once);
}
Unit under test:
public class ClientGroupMappingService : IClientGroupMappingService
{
private readonly ISubmissionRepository _submissionRepository;
public ClientGroupMappingService(IServiceProvider serviceProvider)
{
_submissionRepository = serviceProvider.GetRequiredService<ISubmissionRepository>();
}
public void ProcessClientGroupMappingImport(Guid submissionID)
{
Submission submission = _submissionRepository.GetOne(submissionID).Value;
submission.SubmissionStatus = SubmissionStatus.Processing;
_submissionRepository.Save(submission);
// ..other stuff
}
}
Moq.MockException :
Expected invocation on the mock once, but was 0 times: c => c.Save(It.Is<Submission>(d => (int)d.SubmissionStatus == 2))
So Verify should see that the call was made to Save, and the param passed to Save matches the condition in the supplied predicate. My knee-jerk reaction is that once I pull the object out of the mock using submissionRepositoryMock.Object, I am no longer tracking the Mock, so calls to the Object are not going to register on the Mock. But if this is the case, what is the correct way to verify that my method made the required call?
The issue was in the "// ...other stuff" that I took out for brevity.
Later on in the method, the SubmissionStatus is updated again, and Mock.Verify only seems to be evaluating the REFERENCE to the object that was passed into the Save call as opposed to the VALUE, as all of the Invocations of Save show that it was called with SubmissionStatus.Success (which isn't actually true).
Hope this makes sense and helps anyone with a similar problem.

Unable to get data from ajax function call from WCF service in first attempt

[WebMethod]
public static string LoadAccount()
{
address = new EndpointAddress(objClientSession.ServiceURL);
proxy = new PMToolServices.MyAppServiceClient(binding, address);
//Now call the web service to get the accounts
proxy.wsGetAccountsCompleted += new EventHandler<MyAppServices.wsGetAccountsCompletedEventArgs>(proxy_wsGetAccountsCompleted);
proxy.wsGetAccountsAsync();
return strAccountList;
}
I am calling LoadAccount WebMethod using ajax. In LoadAccount I have added callback proxy_wsGetAccountsCompleted to wsGetAccounts of WCF. In proxy_wsGetAccountsCompleted I'm building result to return to LoadAccount.
Issues:
I'm unable to return result directly from 'proxy_wsGetAccountsCompleted' so I've stored that result in global defined string and then at the end of LoadAccout WebMethod returning that. Can I return that directly from proxy_wsGetAccountsCompleted.
When I call LoadAccount WebMethod first time it returning blank result and if I call again second time then I get correct result. Even though as sequence I'm returning that global defined string after proxy_wsGetAccountsCompleted above it. Is that right?
Confused about sequence/return response between:
proxy.wsGetAccountsAsync();
proxy_wsGetAccountsCompleted();
return strAccountList
You are doing something strange: calling a wcf operation that is synchonous, that calls an asynchonous operations. Of course the first time it will not works.
LoadAccount() returns prior to get the wsGetAccountsAsync() result. You can either call wsGetAccountsAsync in synchonous way or use an asynchonous operation, like using Signal R.
Remember that when call the operation by the 2nd time, you will get result from previous request, if your method was accepting some parameter, you will store a wrong value, that is the response for your previous request.

Making AutoMoq return Fixture-created values for methods

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.

Moq.MockVerificationException not public xUnit Assert.Throws

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 (() => {});

Moq caches return value

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.

Resources