moq- why can't operate function with default parameter - unit-testing

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.

Related

Typed property App\Http\Livewire\Roles\EditUserRole::$user_model must not be accessed before initialization

// Throw an Error While I have Already Initialized? Please need Help
public function mount()
{
$this->user_model = new User();
$this->userData = $this->user_model->displayUsers();
$this->role_model = $role_model ?? new Role();
$this->roleData = $this->role_model->displayRoles();
}
Try to set default values in your property definitions.
class YouLivewireClass extends Component
{
public string $email = "";
public int $number = 0;
public ?User $user = null;
public function mount()
{
// your logic
}
}
mount() method in Livewire is not the same as a __construct method.
It is called very early but the object is already created and some of the general PHP checks are executed. If you define strict types for the properties that can result in error in Livewire, because they can not fallback to null for the initialisation process.
Here a nice explanation from the Livewire forum: https://forum.laravel-livewire.com/t/1-0-3-typed-property-must-not-be-accessed-before-initialization/320
For anyone wondering why: With the typed properties in 7.4 they have a
state of initialized and uninitialized, instead of the expected
behavior of properties defaulting to a null value if there isn’t one
assigned. In “regular” classes, the properties can maintain an
uninitialized state, and this error is only thrown when you try to
actually access it. Which all makes sense because the point of it all
is to have stricter code.
There’s a few reasons why Livewire (and a portion of Laravel for that
matter) is different than a textbook oop object. First, mount() should
not be thought of as __construct(), and should be thought of closer to
Laravel’s boot() method. The object has been built already, and some
behind the scenes work has been done that makes Livewire work, before
the mount() method is called. mount() is just the first method called
in in the code you provide to Livewire.

jest-fetch-mock with classes that perform api query

All the examples of jest and jest-fetch-mock I have come across use functions that perform an API query and return a payload directly from the function call.
In my case, I have a different setup. I have a class that has a property called 'data'. In the class there is a method called "get" which pulls data using fetch API and stores it in the data property. When the method is called, it simply returns true or false based on promise resolve or reject.
I am trying to figure out how to write unit tests for this in this case. My function doesn't return the data fetched; only a boolean value.
So if I use jestSpyOn to mock the class method, how would I set the data property, and then retrieve the result?
In my code, I do something like this (NOT in testing, but in the actual app):
contactStore = new ContactListStore();
// 'all' is a sample param passed
contactStore.get('all').then(res => {
if(res){
...perform action
}
});
As you can see the res argument is only boolean, and if true, then contactStore.data will contain the information retrieved from the server.
So to run a unit test on it, I need to call a mock get, and set a mock data property.
Any ideas how this would be done?
In your mock method, you just need return true.

RhinoMocks - Getting the value passed into an Indexer (this[])

I need to find out the value passed into an indexer.
My code (c#) that I need to test is as follows:
string cacheKey = GetCacheKey(cacheKeyRequest);
string cachedValue = myCache[cacheKey] as string;
So, I need to be able to identify the value of the "cacheKey" that was passed into the indexer.
I have attempted this using a Mock of the cache object:
var cache = MockRepository.GenerateMock<WebDataCache>();
The idea being that after the code had executed, I would query the mock to identify the value that had been passed into the indexer:
var actualCacheKey = cache.GetArgumentsForCallsMadeOn(a => a["somevalue"], opt => opt.IgnoreArguments())[0][0].ToString();
This gives me a compilation error: Only assignment, call, increment, decrement, and new object expressions can be used as a statement.
I saw one suggestion to make this a function in the following way:
var actualCacheKey = cache.GetArgumentsForCallsMadeOn(a => a["somevalue"] = null, opt => opt.IgnoreArguments())[0][0].ToString();
This now compiles,but throws a run-time InvalidOperationException: No expectations were setup to be verified, ensure that the method call in the action is a virtual (C#) / overridable (VB.Net) method call.
Any suggestions? [Am using RhinoMocks.3.6.1]
Many thanks in advance
Griff
PS - I have previously posted this in http://groups.google.com/group/rhinomocks but after several days the view-count remains depressingly low.
The exception tells you exactly what is happening:
InvalidOperationException: No expectations were setup to be verified, ensure that the method call in the action is a virtual (C#) / overridable (VB.Net) method call.
Which means, in order for Rhino to properly work (or, in order for Castle to generate working proxies) your indexer has to be virtual. If you can't make it so, Rhino won't help you in this situation.
Once you make your indexer virtual, it is simple task:
var cache = MockRepository.GenerateMock<WebDataChache>();
cache.Expect(c => c["SomeKey"]).Returns("SomeValue");
// perform actual test
cache.VerifyAllExpectations();
This ensures that cache is accessed with ["SomeKey"]. If key value will be different, test will fail at VerifyAllExpectations line.

google mock : how can I " EXPECT " that no method will be called on a mock

I want to test the in case of some fail no method will be called on a mock object , using google mock.
so the code be something like:
auto mocObj = new MockObj;
EXPECT_NO_METHOD_CALL(mocObj); //this is what I'm locking for
auto mainObj = new MainObj(mocObj , ......and other mocks); // here I simulate a fail using the other mock objects, and I want to be sure the no methods are called on the mockObj
There are no needs to explicitly tell that no methods will be called. If you set the logging level high enough, you should get a message if a method is called (if no expectation is set).
Other then that, you can set expectations like this :
EXPECT_CALL( mockObj, Foo(_) ).Times(0);
on all methods.
Create a StrictMock; any unexpected method call will be a failure.
Use Exactly(0) for all your class methods.
the cardinality will be set to zero so you are expecting no calls
You can also use StrictMock instead of NiceMock. This will fail on any "uninteresting" call, i.e., whenever a method of the mock is called, but no EXPECT_CALL was defined.
See Google Mock documentation here.

Compile error when trying to mock a generic method with Moq

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