c# Mock protected internal virtual function with input as object - c#

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().

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.

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.

assistance with writing a unit test for a method with rhino mocks

I need some assistance with writing a unit test for the following class using Rhino Mocks 3.5. The following overrided method in my class:
public override void Initialize(params object[] messages)
{
var data = new ViewData
{
Name = this.GetName()
};
this.Notify(data);
}
I want to be write a test to validate that when the Initialize method is called, the method calls the Notify method and has a parameter of type ViewData. Also I want to check that the GetName method which is a private method is called within this method. I use an accessor to access the GetName private method.
Any help would be great with this as I am new to writing tests and need assistance.
What you want is called a partial mock.
[Test]
public void UsingPartialMocks()
{
MockRepository mocks = new MockRepository();
YourClass partialMock = mocks.PartialMock<YourClass>();
Expect.Call(partialMock.Notify(null)).IgnoreArguments();
mocks.ReplayAll();
partialMock.Initialize(null);
mocks.VerifyAll();
}
While not directly answering your question on how to do it using Rhino (it appears that Jon has done a decent job at that already), for posterity sake I'll show how I would test it using manual mocking. (bear with me, it's been a while since I've done C#, so pardon the syntax errors)
[Test]
public void initializeRegistersViewDataWithGivenName()
{
ShuntedYourClass yourClass = new ShuntedYourClass();
yourClass.initialize( /* arg list */ );
// Verify 'Notify' was called
Assert.NotNull(yourClass.registeredViewData);
// Verify 'GetName' private method was invoked and
// 'Name' was properly populated
Assert.AreEqual("expected name", yourClass.registeredViewData.Name);
}
// Nested class for testing purposes only.
class ShuntedYourClass : public YourClass
{
public ViewData registeredViewData;
public override void Notify(ViewData vd)
{
this.registeredViewData = vd;
}
}
This code now verifies that the Initialize method does indeed work properly and executes the Notify with the proper parameters.
Hope that helps!
Brandon

RhinoMocks AssertWasCalled on mocked object's method that needs to have an object returned?

Using RhinoMocks, I have a catch-22 situation: I want to verify that a method is called, but this method needs to have an object returned on it because the returned object is acted on in the next line. In other words, mocking on the interface just returns a null value, but not mocking it up doesn't give me any way to verify that the method was called apart from some kind of integration test.
Therefore, looking at the contrived sample below that I threw together, is there a way to do what I'm wanting? I thought there might be a way to set the AssertWasCalled method to actually return something as when stubbing a method, but...thanks for any pointers (especially if it's simply a design flaw that should be addressed instead).
public class SomeClass
{
private readonly ISomeMapper _someMapper;
[Inject]
public Test(ISomeMapper someMapper)
{
_someMapper = someMapper;
}
public SomeReturnType SomeMethod(IEnumerable<ISomethingToMap> somethings)
{
//foreach over somethings and do something based on various properties for each
MappedSomething mappedSomething = _someMapper.Map(something); // AssertWasCalled here
mappedSomething.SomeProperty = somethingFromSomewhere; // Which gets a null reference exception here (understandably) if _someMapper is mocked
//end foreach after more stuff
}
}
///...
[Test]
public void the_mapper_should_be_called()
{
//If mock or stub, then can AssertWasCalled, but then only null object returned.
// If don't mock, then cannot assert whether was called.
var mapper = MockRepository.GenerateStub<ISomeMapper>();
var somethingToMap = _someListOfSomethings[0];
var sut = new SomeClass(mapper);
sut.SomeMethod(_someListOfSomethings);
mapper.AssertWasCalled(x => x.Map(somethingToMap));
}
You can set an expectation on the mock object that the method was called along with the return value:
MappedSomething fakeMappedSomething = //whatever
mapper.Expect(m => m.Map(something)).Return(fakeMappedSomething);
...
sut.SomeMethod(_someListOfSomethings);
Then verify the expectations at the end of the test.

Moq'ing an interface

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);
}

Categories

Resources