So I have this main() method that calls printResult() method and the printResult() has a lambda argument on second parameter like this:
class SomeClass() {
fun main(value: Int) {
printResult(value){ it ->
it + it
}
}
fun printResult(value: Int, sum: (Int) -> Int) {
val result = sum(value)
println(result)
}
}
Then in the unit test, I want to verify that every time the main() method is called, the printResult() should be invoked as well. So I write the unit test like this:
#Test
fun testMain_shouldInvokePrintResult() {
someClass.main(10)
verify(someClass).printResult(10){ any() }
}
I don't know what argument I should pass for printResult() method, that's why I used any(). But when I run the test, the compiler said:
Argument(s) are different! Wanted:
someClass.main(
10,
() (kotlin.Exception /* = java.lang.Exception */) -> kotlin.Unit
);
-> at com.mydomain.test.testMain_shouldInvokePrintResult(SomeClassTest.kt:49)
Actual invocations have different arguments:
someClass.main(
10,
() (kotlin.Exception /* = java.lang.Exception */) -> kotlin.Unit
);
-> at com.mydomain.SomeClass.printResult$lambda-27(SomeClass.kt:20)
So the compiler basically said different arguments but showed me no different on both invocation. What should I do? any help would be appreciated..
It solved. So my colleagues told me to use any() inside parenthesis instead of the curly brackets. So it would be like this:
#Test
fun testMain_shouldInvokePrintResult() {
someClass.main(10)
verify(someClass).printResult(10, any())
}
Related
Regex::replace_all has the signature fn (text: &str) -> Cow<str>. How would two calls to this be written, f(g(x)), giving the same signature?
Here's some code I'm trying to write. This has the two calls separated out into two functions, but I couldn't get it working in one function either. Here's my lib.rs in a fresh Cargo project:
#![allow(dead_code)]
/// Plaintext and HTML manipulation.
use lazy_static::lazy_static;
use regex::Regex;
use std::borrow::Cow;
lazy_static! {
static ref DOUBLE_QUOTED_TEXT: Regex = Regex::new(r#""(?P<content>[^"]+)""#).unwrap();
static ref SINGLE_QUOTE: Regex = Regex::new(r"'").unwrap();
}
fn add_typography(text: &str) -> Cow<str> {
add_double_quotes(&add_single_quotes(text)) // Error! "returns a value referencing data owned by the current function"
}
fn add_double_quotes(text: &str) -> Cow<str> {
DOUBLE_QUOTED_TEXT.replace_all(text, "“$content”")
}
fn add_single_quotes(text: &str) -> Cow<str> {
SINGLE_QUOTE.replace_all(text, "’")
}
#[cfg(test)]
mod tests {
use crate::{add_typography};
#[test]
fn converts_to_double_quotes() {
assert_eq!(add_typography(r#""Hello""#), "“Hello”");
}
#[test]
fn converts_a_single_quote() {
assert_eq!(add_typography("Today's Menu"), "Today’s Menu");
}
}
Here's the best I could come up with, but this will get ugly fast when composing three or four functions:
fn add_typography(input: &str) -> Cow<str> {
match add_single_quotes(input) {
Cow::Owned(output) => add_double_quotes(&output).into_owned().into(),
_ => add_double_quotes(input),
}
}
A Cow contains maybe-owned data.
We can infer from what the replace_all function does that it returns borrowed data only if substitutions did not happen, otherwise it has to return new, owned data.
The problem arises when the inner call makes a substitution but the outer one does not. In that case, the outer call will simply pass its input through as Cow::Borrowed, but it borrows from the Cow::Owned value returned by the inner call, whose data now belongs to a Cow temporary that is local to add_typography(). The function would therefore return a Cow::Borrowed, but would borrow from the temporary, and that's obviously not memory-safe.
Basically, this function will only ever return borrowed data when no substitutions were made by either call. What we need is a helper that can propagate owned-ness through the call layers whenever the returned Cow is itself owned.
We can construct a .map() extension method on top of Cow that does exactly this:
use std::borrow::{Borrow, Cow};
trait CowMapExt<'a, B>
where B: 'a + ToOwned + ?Sized
{
fn map<F>(self, f: F) -> Self
where F: for <'b> FnOnce(&'b B) -> Cow<'b, B>;
}
impl<'a, B> CowMapExt<'a, B> for Cow<'a, B>
where B: 'a + ToOwned + ?Sized
{
fn map<F>(self, f: F) -> Self
where F: for <'b> FnOnce(&'b B) -> Cow<'b, B>
{
match self {
Cow::Borrowed(v) => f(v),
Cow::Owned(v) => Cow::Owned(f(v.borrow()).into_owned()),
}
}
}
Now your call site can stay nice and clean:
fn add_typography(text: &str) -> Cow<str> {
add_single_quotes(text).map(add_double_quotes)
}
I currently have the following function:
fun createMask(mask : String){
val ssnField : mywidgets.SSNField = findViewById (R.id.editTextText)
ssnField.hint = mask
}
To unit test this I want to wrap the untestable code within createMask into a closure. (The untestable code is the view layer logic that's difficult to instantiate and execute in a unit test.) Here is what I want to do in pseudo code:
createMask(closure, mask : String){
closure = mask // closure function returns pointer to property (depending on closure return type, might need to use setter: closure.set(mask))
}
With the above, the caller then does:
fun caller(){
createMask((){
val ssnField : mywidgets.SSNField = findViewById (R.id.editTextText)
return ssnField.hint
}, "xxx-xx-xxx")
}
How do do what is expressed in pseudo code work in kotlin?
You can return a reference of the property if you make createMask accept a parameter of type () -> KMutableProperty0<String>. Then you can call the set method:
fun createMask(mask : String, block: () -> KMutableProperty0<String>) {
block().set(mask)
}
// caller
createMask("xxx-xx-xxx") {
val ssnField = ...
ssnField::hint
}
Alternatively, use (String) -> Unit to represent "any function that takes a string", if you want to allow callers to pass any function that has the "form" of a setter.
fun createMask(mask : String, block: () -> (String) -> Unit) {
block()(mask)
}
// caller
createMask("xxx-xx-xxx") {
val ssnField = ...
ssnField::hint.setter
}
Note that this method involves reflection, which may not be desirable. Alternatively, you can accept a closure that takes the string to be set, and let the caller set it in the closure:
fun createMask(mask: String, block: (String) -> Unit) {
block(mask)
}
// caller
createMask("xxx-xx-xxx") {
val ssnField = ...
// note that rather than responsible for returning a property, the caller
// is responsible for setting "it" to the property
ssnField.hint = it
}
(I'm assuming createMask does more than just setting a property. Otherwise it is quite pointless...)
I'm having a hard time trying to get a private method in Kotlin using reflection in order to pass it as a parameter to a higher order function, here is what I got and what I need to do:
The function that gets the private method, probably what I should change or fix:
inline fun <reified T> T.getPrivateFunc(name: String): KFunction<*> {
return T::class.declaredMemberFunctions.first {
it.name == name
}.apply {
isAccessible = true
}
}
This is the high order function I have:
class MyService {
fun myHigherOrderFunction(action: () -> Unit) { /*...*/ }
}
These are the class and the private method I need to get somehow:
class SystemUnderTest {
fun privateFunc() { /*...*/ }
}
Finally a unit test where I I'm trying to make sure the proper method is passed to the high order function, I omitted details for simplification:
// ...
val serviceMock = MyService()
val sut = SystemUnderTest()
// Here is what I'm trying to accomplish
val privateMethod = sut.getPrivateMethod("privateFunc")
service.myHighOrderFunction(privateMethod)
// In the above line I get a compilation error: required () - Unit, found KFunction<*>
service.myHigherOrderFunction(privateMethod as () -> Unit)
// In the above line I get the following runtime error:
// ClassCastException: kotlin.reflect.jvm.internal.KFunctionImpl cannot be cast to kotlin.jvm.functions.Function1
I know the test can be done having the privateFunc as public and maybe annotating it with #VisibleForTesting, but what I want is to avoid compromising the design as long as I can.
Any ideas? Thanks in advance!
I don't think KFunction and KCallable have any notion of a bound receiver, so they are not invokable (have no operator fun invoke), and therefore don't qualify as functions. So I think you have to wrap the KFunction object in a function to be able to pass it to your higher order function. To call a KFunction, you pass the instance of the receiver class as the first argument.
val serviceMock = MyService()
val sut = SystemUnderTest()
val privateMethod = sut.getPrivateMethod("privateFunc")
service.myHighOrderFunction { privateMethod.call(sut) }
Edit: To internalize the creation of the wrapped function, you could do this:
inline fun <reified T> T.getZeroArgPrivateMethod(name: String): () -> Unit = {
T::class.declaredMemberFunctions.first {
it.name == name
}.apply {
isAccessible = true
}.call(this)
}
//...
val serviceMock = MyService()
val sut = SystemUnderTest()
val privateMethod = sut.getZeroArgPrivateMethod("privateFunc")
service.myHighOrderFunction(privateMethod)
As per Kotlin Unit Testing for Function Parameter and Object, we could test the function variable funcParam, as it is an object function variable.
However if code is written using anonymous/inlining function parameter (which is a very nice Kotlin feature, that allow us to eliminate unnecessary temp variable for it)...
class MyClass1(val myObject: MyObject, val myObject2: MyObject2) {
fun myFunctionOne() {
myObject.functionWithFuncParam{
num: Int ->
// Do something to be tested
myObject2.println(num)
}
}
}
class MyObject () {
fun functionWithFuncParam(funcParam: (Int) -> Unit) {
funcParam(32)
}
}
How to write my unit test that test this part of code?
num: Int ->
// Do something to be tested
myObject2.println(num)
Or the inlining of the function parameter (as above) is something not good for unit testing, and hence should be avoided?
After a while discover the way to test it is to use Argument Captor.
#Test
fun myTest() {
val myClass1 = MyClass1(mockMyObject, mockMyObject2)
val argCaptor = argumentCaptor<(Int) -> Unit>()
val num = 1 //Any number to test
myClass1.myFunctionOne()
verify(mockMyObject).functionWithFuncParam(argCaptor.capture())
argCaptor.value.invoke(num)
// after that you could verify the content in the anonymous function call
verify(mockMyObject2).println(num)
}
For more info, refer to https://medium.com/#elye.project/how-to-unit-test-kotlins-private-function-variable-893d8a16b73f#.1f3v5mkql
I'm working with Golang, and currently I'm doing some fun unit test with Testify, my file look like this
type myStruct struct {
field_1 string
}
func (self *myStruct) writeFirst() {
//doing something
//modify field_1
self.writeSecond()
}
func (self *myStruct) writeSecond() {
//doing something
}
In this case I'm testing writeFirst() but I'm trying to replace writeSecond() because it is using http stuff that I don't want to use because it access to internet.
I think that use a second struct and set myStruct as anonymous field will be the solution, but it's not working because me second struct and myStruct have a diferent context.
In this case I can't use mocks cause writeSecond is a method of the struct.
My test case looks like this:
func TestWriteFirst(t *testing.T) {
myStc := myStruct{}
assert.Equal(t,"My response", myStc.field_1)
}
All that I want is testing writeFirst without pass to writeSecond()
To illustrate the kind of refactoring mentioned by Not-a-Golfer in the comments, you could consider calling your second function only on an instance that is an interface:
type F2er interface {
Func2()
}
type S struct{ _f2 F2er }
var s = &S{}
func (s *S) f2() F2er {
if s._f2 == nil {
return s
}
return s._f2
}
func (s *S) Func1() {
fmt.Println("s.Func1")
s.f2().Func2()
}
Here: Func1 calls Func2 on s.f2(), not directly s.
If nothing has been set in s, s.f2() returns... itself: s
if s._f2 was replaced by any other struct which implements Func2, s.f2() returns that instance instead of itself.
See a complete example in this playground script.
Output:
TestFunc1
s.Func1
s.Func2
TestFunc1bis
s.Func1
testS.Func2 <=== different Func2 call