Compile error when trying to mock a generic method with Moq - unit-testing

I have a method I'd like to mock:
public interface IServiceBus
{
void Subscribe<T>(ISubscribeTo<T> subscriber) where T : class;
}
For the sake of this example, T can be something called SomeType.
Now, I'd like to mock this, like so:
var mockServiceBus = new Mock<IServiceBus>();
mockServiceBus.Setup(x => x.Subscribe(It.IsAny<ISubscribeTo<SomeType>>));
However, when I try this, I get this compile error:
Error 65
The type arguments for method 'ServiceBus.IServiceBus.Subscribe(Messaging.ISubscribeTo)'
cannot be inferred from the usage.
Try specifying the type arguments
explicitly.
I'm not sure how to work around this error. Any ideas? Or is this behavior not possible to mock with Moq?

try this (adding parentheses since It.IsAny<TValue> is a method):
mockServiceBus.Setup(x => x.Subscribe(It.IsAny<ISubscribeTo<SomeType>>()));

Related

Mock extensions function inside Companion Object

I have a class (class A) to which I define an extension function (A.extension()) inside a companion object of another class (class B) for a matter of organization.
On my tests I need:
To use a real class A instance .
To mock A.extension().
To use a mock instance of class B.
Using MockK-library I am not being able to mock that extension function successfully.
I've tried:
mockkObject(B.Companion) {
every { any<A>().extension() } returns whatIneed
}
result: Tries to run the unmocked version of the extension function.
mockkStatic(path.to.B.CompanionKt)
every { any<A>().extension() } returns whatIneed
Result: It does not find the Companion Object.
mockkStatic(A::extension) {
every { any<A>().extension() } returns whatIneed
}
Result: Compile error -> 'extension' is a member and an extension at the same time. References to such elements are not allowed.
Am I missing something regarding how to mock this ?
Am I doing something wrong in terms of code structuring that prevents this mocking to be possible?
Any help is appreciated.
This seems to be an impossible thing. I have tried this severally and it does not work.

How to address NodeJS's built-in functions with Sinon?

Using Sinon stubs, I have successfully stubbed functions along the project, using the traditional stubbing syntax:
const permissionsStub = sinon.stub(invitation, 'update')
sinon.assert.calledOnce(permissionsStub)
Now I am trying to Stub a built-in function of NodeJS (findIndex, indexOf, etc..), without success, as it should be passed with the in the first argument of Sinon's stub() function call, and as that is a NodeJS's core function, what needs to be passed?
I have tried creating an empty stub and then assigning it directly to the function in the code, but I think there is a simpler way to try and spy/stub/mock built-in NodeJS functions.
I get this error by trying to pass a few arguments that might target it correctly, as it doesn't succeed mounting:
TypeError: Cannot read property 'returns' of undefined
How can I target those functions in a simpler way using Chai and Sinon?
So eventually I got it to work using the following code (rewire is being used to get to the inner unexported functions of the file):
const permissionIndex = invitation.__get__('permissionIndex')
permissionsStub.findIndex = () => {
return { id: 1 }
}
expect(permissionIndex(1, permissionsStub)).to.be.an('object')
expect(permissionIndex(1, permissionsStub)).to.have.deep.property('id', 1)

Mockery cannot create a partial mock with Eloquent Model fill method

I'm trying to test a Laravel api.
When I try to create a partial mock with the Eloquent Model fill method, phpunit throws an error.
Code
$mock = m::mock('App\User', [])->makePartial();
$mock->shouldReceive('fill')->once()->andReturn('ok');
$result = $mock->fill([]);
var_dump($result);
Error
PHP Fatal error: Call to a member function __call() on a non-object
PHP Fatal error: Uncaught exception 'Illuminate\Contracts\Container\BindingResolutionException' with message 'Target [Illuminate\Contracts\Debug\ExceptionHandler] is not instantiable.
I really don't know if this either a Eloquent bug, or a Mockery error.
Notes:
I temporarily solved this problem using Model::update method instead of Model::fill and then Model::save, but I still want to know how to mock the fill method.
Links
http://laravel.com/api/5.0/Illuminate/Database/Eloquent/Model.html#method_fill
I think the mock object is created but without this method. You will need to define an expectation for the fill() method to dictate her mocked behaviour. like:
$mock->shouldReceive('fill')->once()->andReturn('ok');
hope it helps.
You can also use a passive partial mock as:
$mock = m::mock('Model')->makePartial();
$mock->shouldReceive("fill")->once()->andReturn("ok");
In passive partial, all methods will simply defer to the parent class original methods unless a method call matches a known expectation. And it will skip the call of the unexpected fill method in Model constructor.

moq- why can't operate function with default parameter

I am trying to make a unit test on a very simple interface.
my interface is:
public interface Interface1
{
string retStr(string dd);
string retStr2(string dd,string fff);
}
this is the mock:
var myMoq = new Mock<Interface1>();
myMoq.Setup(d => d.retStr("David")).Returns("retStr");
Console.WriteLine(myMoq.Object.retStr("fdf").ToString());
I GOT runtime error: Object reference not set to an instance of an object.
and another error on implementation:
myMoq.Setup(d => d.retStr2(It.Is<string>(e=>e=="qqq"), It.IsAny<string>())).Returns("2 parameters");
Console.WriteLine(myMoq.Object.retStr2("fdf","wewew").ToString());
Why is it?
In your setup, you are setting the expectation that a specific string will be passed in (for example "David").
You are telling Moq, "Pass back "retStr" if the method invoked with the string "David", otherwise return a default value (for string, null). Because of this, when you do a .ToString() on the result of the method, the object is null.
The same thing applies to the second example.
In order to make a more general return value, use It.IsAny<string>() when setting up a method. Or, do as you expect in the test and send in "David" when you call the method.

How do you assert a generic method was called with Rhino Mocks?

I have the following test to verify that my repository is calling it's respective session (I've rewritten it to highlight the actual problem):
[Test]
public void Why_Does_This_Fail()
{
var objectUnderTest = new SomeGenericsProblem();
var fakeSession = MockRepository.GenerateMock<ISession>();
fakeSession.Expect(s => s.Query<SomeClass>());
objectUnderTest.NotWorking<SomeClass>();
fakeSession.AssertWasCalled(t => t.Query<SomeClass>());
}
but when I run the test I get this:
System.InvalidOperationException :
Invalid call, the last call has been
used or no call has been made (make
sure that you are calling a virtual
(C#) / Overridable (VB) method).(C#) / Overridable (VB) method).
Any ideas what I'm doing wrong here? The session that I'm mocking is an interface, so it has to be virtual/overridable.
I have a feeling it has something to do with the fact that my Query method is a generic, but I don't know any other way to express what I'm trying to test.
Also, If I remove the part that sets up the expectation (i.e. this line of code:)
fakeSession.Expect(s => s.Query<SomeClass>());
I get a different exception which is equally confusing to me:
System.InvalidOperationException : No
expectations were setup to be
verified, ensure that the method call
in the action is a virtual (C#) /
overridable (VB.Net) method calloverridable (VB.Net) method call
So I figured out what was wrong.
ISession comes from NHibernate, which I probably should have mentioned.
The reason why this is cruicialy important is because
session.Query<T>
(which is what I'm trying to mock), is an EXTENSION METHOD.
Rhino Mocks apparently does not have the capability of mocking extension methods, hence why it's giving me the weird error.
So hopefully I'll have saves someone else the time and agony I've gone through in trying to figure out why my test won't pass.
The only solution that I've read about for this is to actually change the design of the extension method (which I can't do because it's part of NHibernate), or to use a different mocking framework like TypeMock.
[Test]
public void Query_WhenCalled_CallsSessionQuery()
{
// arrange
var session = MockRepository.GenerateStub<ISession>();
var r = new Repository(session);
// act
r.Query<SomeClass>();
// assert
session.AssertWasCalled(s => s.Query<SomeClass>());
}