'invocation failed' and 'setups were not matched' at the same time - c#

I'm writting some unit tests and mocking some parts. I understand both the meanings of these errors seperately. My problem is that they occur at the same time and for the same method, but I can mock other methods of the same class. It's just that one particular method.
I already checked if:
there is confusion with different namespaces and same class names
there are methods with same names but different signatures
the mocking is happening after the method call. This is how the test looks like. I use the same structure for other methods of the same class and there is no problem:
private readonly Mock<IDependency> mockDependency;
[Fact]
public void GetSomeThingByIdTest()
{
SetupMock();
ITestedInterface testedClass = CreateTestedImpl();
ISomeThing expected = new SomeThing();
ISomeThing mocked = testedClass.GetSomeThingById("someId");
Assert.Equal(expected, mocked);
}
private void SetupMock()
{
var mockSomeThing = new Mock<ISomeThing>();
mockDependency.Setup(x => x.GetSomeThingById("someId")).Returns(mockSomeThing.Object);
}
private ITestedInterface CreateTestedImpl() => new Tested(mockDependency.Object);
I get:
Moq.MockException
ITestedInterface.GetSomeThingById(someId) invocation failed with mock behavior Strict.
and
Moq.MockException
The following setups were not matched:
ITestedInterfacex => x.GetSomeThingById(someId)
at the same time.
Any ideas why this is happening?

Related

Difficulties mocking ILogger and verifying method calls

I'm trying to test that one of my controller end points calls the LogError once. This is the test:
[Fact]
public void Log_error_should_call_logger_error_method()
{
//Arrange
var applicationException = new ApplicationException("This is a mocked exception");
var exceptionHandlerFeatureMock = ErrorsControllerGenerator.GenerateExceptionHandlerFeatureMock(applicationException);
Mock<ILogger<ErrorsController>> iLoggerMock = new Mock<ILogger<ErrorsController>>();
var sut = ErrorsControllerGenerator.GenerateErrorsController(exceptionHandlerFeatureMock, iLoggerMock);
//Act
sut.LogError("This is a test error");
//Assert
iLoggerMock.Verify(x => x.LogError("This is a test error"), Times.Once());
}
I'm receiving the following error when running the test:
System.NotSupportedException : Invalid verify on a non-virtual (overridable in VB) member: x => x.LogError("This is a test error", new[] { })
I'm slightly confused by this as from what I understand, this shouldn't happen because I'm mocking the interface rather than the concrete implementation? If I was to use the concrete logger class, I know that the method would have to be marked as virtual for this to work but I didn't think that was the case when using interfaces.
I've tried adding this line to the //Arrange part of the test:
iLoggerMock.Setup(x => x.LogError(It.IsAny<string>())).Verifiable();
But this just throws this error instead:
System.NotSupportedException : Expression references a method that does not belong to the mocked object: x => x.LogError(It.IsAny<String>(), new[] { })
This also confuses me as the mocked object (ILogger) does have a LogError method
You can't mock logger methods such as LogError because unfortunately they are extension methods and are not defined in the ILogger interface.
Instead of trying to verify whether the relevant log methods were called, perhaps you could verify the executed code takes the expected path i.e. the path where the relevant log methods would be called.

How to setup a non-virtual members uning nunit moq technique? [duplicate]

I have a unit test where I have to mock a non-virtual method that returns a bool type
public class XmlCupboardAccess
{
public bool IsDataEntityInXmlCupboard(string dataId,
out string nameInCupboard,
out string refTypeInCupboard,
string nameTemplate = null)
{
return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
}
}
So I have a mock object of XmlCupboardAccess class and I am trying to setup mock for this method in my test case as shown below
[TestMethod]
Public void Test()
{
private string temp1;
private string temp2;
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
_xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false);
//exception is thrown by this line of code
}
But this line throws exception
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Any suggestion how to get around this exception?
Moq cannot mock non-virtual methods and sealed classes. While running a test using mock object, MOQ actually creates an in-memory proxy type which inherits from your "XmlCupboardAccess" and overrides the behaviors that you have set up in the "SetUp" method. And as you know in C#, you can override something only if it is marked as virtual which isn't the case with Java. Java assumes every non-static method to be virtual by default.
Another thing I believe you should consider is introducing an interface for your "CupboardAccess" and start mocking the interface instead. It would help you decouple your code and have benefits in the longer run.
Lastly, there are frameworks like : TypeMock and JustMock which work directly with the IL and hence can mock non-virtual methods. Both however, are commercial products.
As help to anybody that had the same problem as me, I accidentally mistyped the implementation type instead of the interface e.g.
var mockFileBrowser = new Mock<FileBrowser>();
instead of
var mockFileBrowser = new Mock<IFileBrowser>();
Instead of mocking concrete class you should mock that class interface.
Extract interface from XmlCupboardAccess class
public interface IXmlCupboardAccess
{
bool IsDataEntityInXmlCupboard(string dataId, out string nameInCupboard, out string refTypeInCupboard, string nameTemplate = null);
}
And instead of
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
change to
private Mock<IXmlCupboardAccess> _xmlCupboardAccess = new Mock<IXmlCupboardAccess>();
Please see
Why does the property I want to mock need to be virtual?
You may have to write a wrapper interface or mark the property as virtual/abstract as Moq creates a proxy class that it uses to intercept calls and return your custom values that you put in the .Returns(x) call.
You'll get this error as well if you are verifying that an extension method of an interface is called.
For example if you are mocking:
var mockValidator = new Mock<IValidator<Foo>>();
mockValidator
.Verify(validator => validator.ValidateAndThrow(foo, null));
You will get the same exception because .ValidateAndThrow() is an extension on the IValidator<T> interface.
public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
In my case I was on Moq version lower than 4.16 and was using .Result syntax to mock an async method which is supported only starting with Moq 4.16
On mock version less than 4.16 following results into Invalid setup on a non-virtual member ... even while using Interface.
mock.Setup(foo => foo.DoSomethingAsync().Result).Returns(true);
On Moq version lower than 4.16 use following
mock.Setup(foo => foo.DoSomethingAsync()).ReturnsAsync(true);
For more see Async Methods Moq Wiki at Github
Code:
private static void RegisterServices(IKernel kernel)
{
Mock<IProductRepository> mock=new Mock<IProductRepository>();
mock.Setup(x => x.Products).Returns(new List<Product>
{
new Product {Name = "Football", Price = 23},
new Product {Name = "Surf board", Price = 179},
new Product {Name = "Running shose", Price = 95}
});
kernel.Bind<IProductRepository>().ToConstant(mock.Object);
}
but see exception.

Mocking UnityContainer RegisterType results in System not supported exception

Hi I am having a hard time mocking IUnityContainer , specificaly I am trying to see if Register Type was called.This is the method I am trying to test:
private readonly IUnityContainer _container;
public InjectorContainer(IUnityContainer container)
{
_container = container;
}
public void RegisterType(InjectorServiceModel dependencyService)
{
_container.RegisterType(dependencyService.From, dependencyService.To);
}
This is my Unity test class:
private Mock<IUnityContainer> _unitContaineMock;
private InjectorContainer _injectorContainer;
[TestInitialize]
public void Initializer()
{
_unitContaineMock = new Mock<IUnityContainer>();
_injectorContainer = new InjectorContainer(_unitContaineMock.Object);
}
[TestMethod]
public void RegisterType_CheckIfContainerRegisterTypeIsCalled_Oance()
{
//Arrange
var injectorServiceModel = new InjectorServiceModel()
{
From = typeof(IInjectorContainerFake),
To = typeof(InjectorContainerFake)
};
bool wasCalled = false;
_unitContaineMock.Setup(x => x.RegisterType(It.IsAny<Type>(), It.IsAny<Type>())).Callback(() =>
{
wasCalled = true;
});
//Act
_injectorContainer.RegisterType(injectorServiceModel);
//Assert
Assert.IsTrue(wasCalled);
}
The code in this state is actual my second attemt I first tryed doing it like this:
[TestMethod]
public void RegisterType_CheckIfContainerRegisterTypeIsCalled_Oance()
{
//Arrange
var injectorServiceModel = new InjectorServiceModel()
{
From = typeof(IInjectorContainerFake),
To = typeof(InjectorContainerFake)
};
//Act
_injectorContainer.RegisterType(injectorServiceModel);
//Assert
_unitContaineMock.Verify(x => x.RegisterType(It.IsAny<Type>(), It.IsAny<Type>()), Times.Once);
}
In both case I get a SystemNotSuported exception that has this message:
Invalid verify on a non-virtual (overridable in VB) member: x =>
x.RegisterType(It.IsAny(), It.IsAny(), new[] { })
From what I could understand from this it seems that when it is trying to veryfying it is looking for a RegisterType with 3 paramaters.
Does anyone know what am I doing wrong here?
I am trying to test if RegisterType has been called.
I'm 99% sure the reason you're getting this is because the RegisterType overload you're calling is actually an extension method defined elsewhere, and you can't use Setup/Verify on extension methods (because they're technically static). I base this on the method list for IUnityContainer here: http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.iunitycontainer_members(v=pandp.30).aspx. The only RegisterType that's actually defined on the interface is this one, which as you can see takes five parameters.
Possible solutions:
Use the overload that takes five parameters instead. You'll be able to do a Verify on that one. But it's of course rather silly to make your code more complex just so you'll be able to write a unit test.
Use a "real" container instead of a mock, and instead of doing a Verify, call one of the IsRegistered overloads in your unit test to check if the type has actually been added to the container. This might be a preferable approach anyway. It will certainly be less brittle. Your unit test shouldn't really care which particular method was used to add the types to the container; it should just verify that the types have been added.

How to write nUnit/Moq for testing generic extension methods?

I have the following generic extension method for deleting all EntityObjects from an ObjectContext
public static void DeleleAllObjects<TEntity>(this ObjectContext context)
where TEntity : EntityObject
{
var objectSet = context.CreateObjectSet<TEntity>();
objectSet.ToList().ForEach(e => objectSet.DeleteObject(e));
}
I'm fairly new to TDD and using nUnit/Moq...but I'm not sure where to being to write tests for this method?
I hope this helps:
[TestFixture]
public class ExtensionTest
{
public class FakeEntity : EntityObject
{
}
[Test]
public void DeleteAllObjects()
{
//arrange
var objectsToDelete = new List<FakeEntity>
{
new FakeEntity(),
new FakeEntity()
};
var mockContext = new Mock<ObjectContext>();
var mockObjectSet = new Mock<ObjectSet<FakeEntity>>();
mockObjectSet.Setup(x => x.ToList()).Returns(objectsToDelete);
mockContext.Setup(x => x.CreateObjectSet<FakeEntity>()).Returns(mockObjectSet.Object);
//act
mockContext.Object.DeleteAllObjects<FakeEntity>();
//assert
mockContext.Verify(x => x.CreateObjectSet<FakeEntity>(), Times.Once());
mockObjectSet.Verify(x => x.ToList(), Times.Once());
mockObjectSet.Verify(x => x.DeleteObject(It.IsAny<FakeEntity>()), Times.Exactly(2));
}
}
Now, this is assuming all your mocked types (the context and the object set) have the methods you invoke declared as virtual or the classes are abstract. Mocking interfaces is usually less restrictive.
Also, if you want to get more picky with your asserts to ensure that indeed DeleteObject is called first with the first instance, and then with the second, and not twice on the first, then you could change that part of the test. But this should serve as a pretty good starting point.
To summarize:
This particular test should only really test the code within your extension method. Meaning, it should only ensure that you call CreateObjectSet<>(), get the list, and then call DeleteObject on each one.
It should not care at all if indeed the DeleteObject() altered the ObjectSet or not (in fact it won't, since it's a mock). That should be the responsibility of a test for the DeleteObject() method, but since I'm assuming that is actually an EF method, you should not write a test for third party components.

How to assert a private method on concrete class is called (TypeMock/NMock/etc..)?

I am trying to write a unit test for the 'IsUnique' function in the class below that looks like this:
class Foo
{
public bool IsUnique(params...)
{
ValidateStuffExists(params);
return CheckUniqueness(params);
}
private void ValidateStuffExists(params)
{
//does some validation
}
private bool CheckUniqueness(params)
{
//does logic to determine if its unique per params
return result;
}
}
The only thing I want to test here is that ValidateStuffExists and CheckUniqueness is called and passed the arguments. That's all this function does so it's all I'm going to test (I'll bend the 'test public behavior only' psuedo-rule and test the private methods here, because its either have one big complicated method/tests or testing 2 private methods).
I am open to any mocking library. I use NMock and didn't think it was up for the Task - so I downloaded TypeMock as I've done reading and heard that this was the best and that it could mock out even concrete classes / non interface method calls...
I'm doing something like this in my test and it throws exception at the 'Isolate.WhenCalled' line:
CrmEntityUniqueValidator_Accessor target = new CrmEntityUniqueValidator_Accessor(); // TODO: Initialize to an appropriate value
DynamicEntity entity = null; // TODO: Initialize to an appropriate value
string[] propertyNames = null; // TODO: Initialize to an appropriate value
bool tru = true;
Isolate.WhenCalled(() => target.CheckUniqueness(entity, propertyNames, null, null)).WillReturn(tru);
target.ValidatePropertiesExist(entity, propertyNames);
Isolate.Verify.WasCalledWithArguments(() => target.ValidatePropertiesExist(entity, propertyNames));
Isolate.Verify.WasCalledWithArguments(() => target.CheckUniqueness(entity, propertyNames, null, null));
This throws an exception like "*** WhenCalled does not support using a method call as an argument."
Even though I'm able to do the same thing with a CLR class - I can mock out DateTime.Now doing this (code works):
DateTime endOfWorld = new DateTime(2012, 12, 23);
Isolate.WhenCalled(() => DateTime.Now).WillReturn(endOfWorld);
DateTime dt = DateTime.Now;
Assert.AreEqual(dt, endOfWorld);
Anyone have any advice here? Do I have to split these 2 methods into a seperate class and make an interface is the only way? or complicate my method/tests??? There must be something I'm missing here... Thanks much for any help in advance.
EDIT: I guess I'm trying to mock out the 2 private methods in the class for the one unit test. How could I do this without having to split out those 2 methods into a seperate class / interface?
try
Isolate.NonPublic.WhenCalled(object,"nonpublic method").IgnoreCall
or Isolate.Verify.NonPublic.WasCalled(object,"method"..
RhinoMocks has the AssertWasCalled method which may serve the purpose of guaranteeing that a method calls another method... but I'm not sure you can do that on a private function of the same class you are unit testing. I think you could only do that if the two methods you wanted to stub were in another dependency class that was injected.

Categories

Resources