Moq'ing an interface - c#

While I'm googling/reading for this answer I thought I would also ask here.
I have a class that is a wrapper for a SDK. The class accepts an ILoader object and uses the ILoader object to create an ISBAObject which is cast into an ISmallBusinessInstance object. I am simply trying to mock this behavior using Moq.
[TestMethod]
public void Test_Customer_GetByID()
{
var mock = new Mock<ILoader>();
var sbainst = new Mock<ISbaObjects>();
mock.Expect(x => x.GetSbaObjects("")).Returns(sbainst);
}
The compiler error reads: Error 1 The best overloaded method match for 'Moq.Language.IReturns.Returns(Microsoft.BusinessSolutions.SmallBusinessAccounting.Loader.ISbaObjects)' has some invalid arguments
What is going on here? I expected the Mock of ISbaObjects to be able to be returned without a problem.

You need to use sbainst.Object, as sbinst isn't an instance of ISbaObjects - it's just the mock part.

Updated, correct code
[TestMethod]
public void Test_Customer_GetByID()
{
var mock = new Mock<ILoader>();
var sbainst = new Mock<ISbaObjects>();
mock.Expect(x => x.GetSbaObjects("")).Returns(sbainst.Object);
}

Related

How to mock IMemoryCache instance methods using Moq that are being hidden by extension methods in C#? [duplicate]

I have a preexisting Interface...
public interface ISomeInterface
{
void SomeMethod();
}
and I've extended this intreface using a mixin...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
I have a class thats calling this which I want to test...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
and a test where I'd like to mock the interface and verify the call to the extension method...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Running this test however generates an exception...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
My question is, is there a nice way to mock out the mixin call?
I have used a Wrapper to get around this problem. Create a wrapper object and pass your mocked method.
See Mocking Static Methods for Unit Testing by Paul Irwin, it has nice examples.
You can't "directly" mock static method (hence extension method) with mocking framework. You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach.
Here is the description of the tool:
Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates.
Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.
You can use Moles with any testing framework (it's independent about that).
I found that I had to discover the inside of the extension method I was trying to mock the input for, and mock what was going on inside the extension.
I viewed using an extension as adding code directly to your method. This meant I needed to mock what happens inside the extension rather than the extension itself.
I like to use the wrapper (adapter pattern) when I am wrapping the object itself. I'm not sure I'd use that for wrapping an extension method, which is not part of the object.
I use an internal Lazy Injectable Property of either type Action, Func, Predicate, or delegate and allow for injecting (swapping out) the method during a unit test.
internal Func<IMyObject, string, object> DoWorkMethod
{
[ExcludeFromCodeCoverage]
get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
set { _DoWorkMethod = value; }
} private Func<IMyObject, string, object> _DoWorkMethod;
Then you call the Func instead of the actual method.
public object SomeFunction()
{
var val = "doesn't matter for this example";
return DoWorkMethod.Invoke(MyObjectProperty, val);
}
For a more complete example, check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.
Like this:
var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);
Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.
public class Foo
{
public void Method()
=> CallToStaticMethod();
protected virtual void CallToStaticMethod()
=> StaticClass.StaticMethod();
}
and test
[TestMethod]
public void MyTestMethod()
{
var expected = new Exception("container exception");
var proxy = new Mock<Foo>();
proxy.Protected().Setup("CallToStaticMethod").Throws(expected);
var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());
Assert.AreEqual(expected, actual);
}
In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).
So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.
It is not perfect, but for unit testing purposes it works well.

c# Mock protected internal virtual function with input as object

I am testing a public API however, internally my API is calling a function with signature like
protected internal virtual void AddBook(Book book)
{
if (null !=book)
bookList= book;
}
And bookList is also defined as
public virtual BookInformation bookList{ get; protected internal set; }
I need to set this bookList. I can do it either using function AddBook or directly accessing bookList. bookList is also defined as "protected internal set".
I tried
var mockModule = new Mock<myModule> { CallBase = true };
mockModule.Protected()
.Setup<Book>("AddBook", book);
But I get error that "AddBook" does not exist.
Any ideas what am I missing?
Update
I was pressed against deadline so I ended up mocking the class. This solved my problem for now.
According to documentation in the Quickstart
if you need argument matching, you MUST use ItExpr rather than It
// at the top of the test fixture
using Moq.Protected;
// in the test
var mock = new Mock<Invitation> { CallBase = true };
// if you need argument matching, you MUST use ItExpr rather than It
// planning on improving this for vNext
mock.Protected()
.Setup<Book>("AddBook", ItExpr.IsAny<Book>());
When you write.Setup<Book>("AddBook", book); this is mocking a method with a return type of Book, but your return type is void. That's why you get an error that AddBook does not exist. You need to call .Setup("AddBook", book) instead.
To mock a protected member you must first include the following at the top of your test fixture:
using Moq.Protected;
You then call Protected() on your mock, after which you can use the generic Setup<> with the return type of your method.
var mock = new Mock<MyClass>();
mock.Protected()
.Setup<int>("MyProtectedGetIntMethod")
.Returns(1);
If the method returns void then use the non-generic Setup().

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.

How to Setup a readonly property with Moq?

I am trying to unit test using Moq. Here is the example code:
public class ConcreteClass
{
private readonly FirstPropery firstProperty;
private readonly SecondProperty secondProperty;
public ConcreteClass(firstProperty, secondProperty)
{
this.firstProperty = firstProperty;
this.secondProperty = secondProperty;
}
}
[TestMethod]
var concreteClassMock = new Mock<ConcreteClass>() { CallBase = true };
In my test method, I want to set firstProperty to reference a real object FirstProperty object (created by a factory), and later use it to test another object's behavior. Is there any way to achieve that?
Usually, you wouldn’t mock private members since you are only mocking the public interface of something. A mock is thus completely independent of implementation details.
That being said, you can pass constructor arguments to the Mock constructor that will then be passed on to the target’s constructor:
new Mock<ConcreteClass>(firstProperty, secondProperty) {CallBase = true};
However, if your goal is to actually test the ConcreteClass, you should not create a mock of it. You should test the actual object. So mock its dependencies and pass those if necessary, but keep the object you want to test actually real. Otherwise, you might introduce and test behavior that comes from the mock instead of the object you are testing:
var firstMock = new Mock<FirstProperty>();
var secondMock = new Mock<FirstProperty>();
var obj = new ConcreteClass(firstMock.Object, secondMock.Object);
obj.DoSomething();
// assert stuff
A few remarks:
1- It could be easily achieve with an interface and a get method like this:
public interface IConcreteClass
{
FirstProperty FirstProperty { get; }
}
[Test]
public void TestCase()
{
var yourFirstPropertyImplementation = new FirstProperty();
var concreteClassMock = new Mock<IConcreteClass>();
concreteClassMock.Setup(o => o.FirstProperty).Returns(yourFirstPropertyImplementation);
}
2- Depending of your scenario, do you really need a Moq, why not just use the true implementation and use moq only at boundaries?
3- You should clarify what you want to test? If it's concrete class? or the properties? or some other classes? The test case I propose in 1 is valid only to test the interaction of concrete class with some other classes.

How can I add an Expression<Action<T>> as an interception to a faked object?

Is there an alternative way to intercept method calls in FakeItEasy if the method and arguments are already represented as an Expression<Action<T>>?
Normally I would simply use
IFoo foo = A.Fake<IFoo>();
A.CallTo(() => foo.SomeMethod("SomeString", A<Exception>.Ignored)).Invokes( ... );
But in my current situation I have a fake IFoo and an Expression<Action<IFoo>> and am trying to marry the two together.
This is actually existing Moq code that I'm re-writing for FakeIEasy but I'm not sure whether it's possible. The Moq version of this is
private void ExampleMoqMethod(Expression<Action<IFoo>> setupAction)
{
Mock<IFoo> Mock = new Mock<IFoo>();
Mock.Setup(setupAction).Callback( ... );
}
I tried the obvious (below) but got a "The specified object is not recognized as a fake object" error (I suspect because the fake object is not being referred to at all!)
private void ExampleFIEMethod(Expression<Action<IFoo>> callSpecification)
{
IFoo foo = A.Fake<IFoo>();
A.CallTo(callSpecification).Invokes( ... );
}
I would hazard a guess that this is possible by implementing IFakeObjectCallRule and using Fake.GetFakeManager(foo).AddRuleFirst(customRule) but I was wondering if there was a more straightforward way doing this?

Categories

Resources