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

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.

Related

Getting System.NullReferenceException : Object reference not set to an instance of an object while mocking

I am writing unit tests using xunit and moq for services in a servic fabric application.
I am passing the mocks like this
private static DataQueueService CreateDataQueueService(
Mock<IServiceBusClientFactory> serviceBusClientFactoryMock )
{
// Exception is being thrown at this line below
serviceBusClientFactoryMock ??= new Mock<IServiceBusClientFactory>();
return new UsageDataQueueService(serviceBusClientFactoryMock.Object);
}
Then test code is ( I have removed the asserts because it is unrelated):
[Fact]
public async Task QueueData()
{
// arrange
Mock<IServiceBusClientFactory> serviceBusClientFactoryMock = new Mock<IServiceBusClientFactory>();
serviceBusClientFactoryMock
.Setup(factory => factory.CreateServiceBusClient(It.IsAny<string>()))
.Returns(It.IsAny<IServiceBusClient>());
// act
DataQueueService dataQueueService = CreateDataQueueService(serviceBusClientFactoryMock: serviceBusClientFactoryMock);
}
I am getting Null Reference Exception. Please help. Is this much context enough to answer the question or is more details needed?
As pointed out by #Alexander Petrov in comments, problem lies in Returns(It.IsAny(). It must return either concrete instance or IServiceBusClient mock.

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

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

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.

Does mocking affect your assertion count?

I'm noticing when I use mock objects, PHPUnit will correctly report the number of tests executed but incorrectly report the number of assertions I'm making. In fact, every time I mock it counts as another assertion. A test file with 6 tests, 7 assert statements and each test mocking once reported 6 tests, 13 assertions.
Here's the test file with all but one test removed (for illustration here), plus I introduced another test which doesn't stub to track down this problem. PHPUnit reports 2 tests, 3 assertions. I remove the dummy: 1 test, 2 assertions.
require_once '..\src\AntProxy.php';
class AntProxyTest extends PHPUnit_Framework_TestCase {
const sample_client_id = '495d179b94879240799f69e9fc868234';
const timezone = 'Australia/Sydney';
const stubbed_ant = "stubbed ant";
const date_format = "Y";
public function testBlankCategoryIfNoCacheExists() {
$cat = '';
$cache_filename = $cat.'.xml';
if (file_exists($cache_filename))
unlink($cache_filename);
$stub = $this->stub_Freshant($cat);
$expected_output = self::stubbed_ant;
$actual_output = $stub->getant();
$this->assertEquals($expected_output, $actual_output);
}
public function testDummyWithoutStubbing() {
$nostub = new AntProxy(self::sample_client_id, '', self::timezone, self::date_format);
$this->assertTrue(true);
}
private function stub_FreshAnt($cat) {
$stub = $this->getMockBuilder('AntProxy')
->setMethods(array('getFreshAnt'))
->setConstructorArgs(array(self::sample_client_id, $cat, self::timezone, self::date_format))
->getMock();
$stub->expects($this->any())
->method('getFreshAnt')
->will($this->returnValue(self::stubbed_ant));
return $stub;
}
}
It's like an assert has been left in one of the framework's mocking methods. Is there a way to show every (passing) assertion being made?
After each test method completes, PHPUnit verifies the mock expectations setup during the test. PHPUnit_Framework_TestCase::verifyMockObjects() increments the number of assertions for each mock object created. You could override the method to undo this if you really want by storing the current number of assertions, calling the parent method, and subtracting the difference.
protected function verifyMockObjects()
{
$count = $this->getNumAssertions();
parent::verifyMockObjects();
$this->addToAssertionCount($count - $this->getNumAssertions());
}
Of course, verifyMockObjects() will throw an assertion failure exception if any expectation is unsatisfied, so you'll need to catch the exception and rethrow it after resetting the count. I'll leave that to you. :)

Resources