We had a few tests in Java and Mockito, which we are progressively converting into Kotlin and Mockk. There's a problem, though. This simple line:
verify(mockedInteractor).setIndex(1);
When we move it to mockk, we get this:
verify { mockedInteractor.index = 1 }
This of course passes the tests, as it's not actually checking that index was set to 1. It's simply setting the mock's variable to 1. This below has the same effect.
verify { mockedInteractor.setIndex(1) }
Is there a way to verify setters?
You could try capture:
val fooSlot = slot<String>()
val mockBar = mockk<Bar>()
every { mockBar.foo = capture(fooSlot) } answers { }
assertEquals(fooSlot.captured, "expected")
Yes you can:
verify { mockedInteractor setProperty "index" value 1 }
There are more examples in here https://mockk.io/#private-functions-mocking--dynamic-calls
Compact solution without hardcoded string:
verify { mockedInteractor setProperty MockedInteractor::index.name value 1 }
where MockedInteractor is mockedInteractor class
I'm wondering if this was asked about an earlier version of Mockk, afterall, it is and old question.
verify { mockedInteractor.index = 1 }
does exactly what it says - it verifies that mockedInteractor.index was set to 1.
If you don't believe me, try it. Try setting mockedInteractor.index to something other than 1 in the product code and watch this test fail.
Maybe this was a Mockk bug that has since been fixed.
You can now relax this requirement for unit functions when defining your mock.
val foo = mockk<Foo>(relaxUnitFun = true)
Enabling this setting on your mock means you will not need to use justRun or any variation of that code (as per the Mockk documentation) when verifying unit functions are invoked.
Related
I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }
Yes, still going with this. My impression is that there's this powerful facility in Raku, which is not really easy to use, and there's so little documentation for that. I'd like to kind of mitigate that.
In this case, I'm trying to force attributes to be read-only by default, to make immutable classes. Here's my attempt:
my class MetamodelX::Frozen is Metamodel::ClassHOW {
method compose_attributes($the-obj, :$compiler_services) {
my $attribute-container = callsame;
my $new-container = Perl6::Metamodel::AttributeContainer.new(
:attributes($attribute-container.attributes),
:attribute_lookup($attribute-container.attribute_table),
:0attr_rw_by_default
);
$new-container.compose_attributes($the-obj, $compiler_services);
}
}
my package EXPORTHOW {
package DECLARE {
constant frozen = MetamodelX::Frozen;
}
}
I'm calling that from a main function that looks like this:
use Frozen;
frozen Foo {
has $.bar;
method gist() {
return "→ $!bar";
}
}
my $foo = Foo.new(:3bar);
say $foo.bar;
$foo.bar(33);
I'm trying to follow the source, that does not really give a lot of facilities to change attribute stuff, so there seems to be no other way that creating a new instance of the container. And that might fail in impredictable ways, and that's what it does:
Type check failed in binding to parameter '$the-obj'; expected Any but got Foo (Foo)
at /home/jmerelo/Code/raku/my-raku-examples/frozen.raku:7
Not clear if this is the first the-obj or the second one, but any way, some help is appreciated.
I upgraded my abp version from 3.5.0 to 7.0.0.
I set method’s attribute UnitOfWork[IsDisabled = true].
Then I run the code like:
xxRepository.GetAllList()
I get the exception:
Value cannot be null. (Parameter 'unitOfWork').
Why? Why not support getalllist in a disabled unitofwork any more? In this case how can I update 1,000,000 data in a loop?
ABP v6.4 introduced a breaking change with the removal of conventional interceptors (for IRepository and IApplicationService) in Minimize interception usage #6165 with an option to allow disabling the removal of conventional interceptors.
You should begin a unit of work explicitly:
using (var uow = unitOfWorkManager.Begin())
{
xxs = xxRepository.GetAllList();
uow.Complete();
}
You can restore the previous behaviour, though this option may be removed in a later version:
return services.AddAbp<AbpProjectNameWebTestModule>(options =>
{
options.SetupTest();
// }); // Change this
}, removeConventionalInterceptors: false); // to this
[UnitOfWork(IsDisabled = true)]
public virtual void RemoveFriendship(RemoveFriendshipInput input)
{
_friendshipRepository.Delete(input.Id);
}
Note that if a unit of work method calls this RemoveFriendship method, disabling this method is ignored, and it will use the same unit of work with the caller method. So, disable carefully! The code above works well since the repository methods are a unit of work by default.
In addition, maybe even disabling the transaction may be sufficient.
References:
https://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#disabling-unit-of-work
https://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#non-transactional-unit-of-work
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/648
I'm writing some unit tests, and I'm stuck writing a test for the following method:
func (database *Database) FindUnusedKey() string {
count := 0
possibleKey := helpers.RandomString(helpers.Config.KeySize)
for database.DoesKeyExist(possibleKey) {
possibleKey = helpers.RandomString(helpers.Config.KeySize + uint8(count/10))
count++
}
return possibleKey
}
I want a test in which helpers.RandomString(int) returns a string that is already a key in my database, but I've found no way to redeclare or monkey patch helpers.RandomString(int) in my test.
I tried using testify mock, but it doesn't seem possible.
Am I doing something wrong?
Thanks.
You can extract database.DoesKeyExist via dependency injection and supply a function that returns true first time in unit tests. More details http://openmymind.net/Dependency-Injection-In-Go/
I am a newbie to Grails and using an ancient version of Grails (1.3.6/8). I have an object with some variables that aren't holding on to the stuff I assign them.
class NiftyController {
try
{
SomeGrid someGrid = new SomeGrid()
def selectedDate = params.specifiedDate
...
someGrid.selectedDate = selectedDate
someGrid.longDate = Calendar.getInstance().getTimeInMillis()
println someGrid.selectedDate // prints, say, 08/06/2012
println someGrid.longDate // prints, say, 1302558890256
....
doSomeWork(someGrid)
}
def doSomeWork = { SomeGrid someGrid ->
println someGrid.selectedDate // prints '' (empty)
println someGrid.longDate // prints 8 - the number for the current month.
}
}
I am totally scratching my head - I work with Java and this type of loss of assigned variable data is new and makes no sense to me at all. Can anyone figure out what is going on here? I would guess it is some kind of visibility problem unique to Grails, but I can't nail it.
Any help is greatly appreciated!
If doSomeWork doesn't itself need to be a controller action, I would make it a normal method instead of a closure:
private doSomeWork(SomeGrid someGrid) {
//...
}
With it as a closure, Grails may be treating the SomeGrid parameter as a command object and trying to data-bind it directly from the params.