Description:
I have already tested methodA() and methodB() so I can be sure that they are covered.
What are the ways to test methodToBeTested() by mocking methodA() and methodB() that are in the same file? The parameters are passed through the methodToBeTested() to the methodA() and methodB() to properly test these methods using injection.
Note: They are cannot be extracted to a different class since it is a related logic of the calculation service and these methods are already atomically is separated.
Code:
class ClassForTesting {
int methodToBeTested(String a, String b) {
// Calculation in this method also is a bit more difficult
return methodA() + methodB();
}
int methodA(String a) {
int value = 1;
// Here is calculation logic that has been tested
return value;
}
int methodB(String b) {
int value = 2;
// Here is calculation logic that has been tested
return value;
}
}
What has been done:
I have tried several approaches from Mockito, but it doesn't allow to do such a trick:
#GenerateMocks - is creating a mock and requires me to stub each method using when(), even methodToBeTested().
By extending Fake using the next construction:
class Mock extends Fake implements PasswordValidatorService {}
But in this way, I'm only inheriting the PasswordValidatorService's behavior instead of instead implementation and each non-overridden method throws UnimplementedError. Thus, I'm not able to override methodToBeTested() and call its super implementation.
I found that Mockito for Java has #Spy construction that would be perfect in this case but unfortunately it is not available for Dart and Flutter.
The only way I currently came is to create my own Mock:
class MockClassForTesting extends ClassForTesting {
#override
int methodA() {
return 2;
}
#override
int methodB() {
return 5;
}
}
But this implementation doesn't allow me to use Mockito's flexibility of when() construction since I must have different methodA() and methodB() returns.
This fact forces me to have additional variables in my MockClassForTesting to achieve when() construction functionality.
The questions:
What would be the best way to achieve my purposes?
Can be the same mocking approach to be used during the Widget testing?
One approach would be to use a hybrid approach where you create your own derived class but where some of its overrides delegate to a Mock implementation. For example:
class ClassForTesting {
int methodToBeTested(String a, String b) {
// Calculation in this method also is a bit more difficult
return methodA(a) + methodB(b);
}
int methodA(String a) {
int value = 1;
// Here is calculation logic that has been tested
return value;
}
int methodB(String b) {
int value = 2;
// Here is calculation logic that has been tested
return value;
}
}
class PartialMockClassForTesting extends ClassForTesting {
final mock = MockClassForTesting();
#override
int methodA(String a) => mock.methodA(a);
#override
int methodB(String b) => mock.methodB(b);
}
#GenerateMocks([ClassForTesting])
void main() {
test('Test partial mock', () {
var partialMock = PartialMockClassForTesting();
when(partialMock.methodA('hello')).thenReturn(42);
when(partialMock.methodA('goodbye')).thenReturn(-42);
when(partialMock.methodB('world')).thenReturn(10);
expect(partialMock.methodToBeTested('hello', 'world'), 52);
expect(partialMock.methodToBeTested('goodbye', 'world'), -32);
});
}
If you want to conditionally mock certain methods, you could have your overrides check boolean flags to conditionally call either the mock or the real implementation. For example:
class PartialMockClassForTesting extends ClassForTesting {
final mock = MockClassForTesting();
final shouldMock = <Function, bool>{};
#override
int methodA(String a) =>
shouldMock[methodA] ?? false ? mock.methodA(a) : super.methodA(a);
#override
int methodB(String b) =>
shouldMock[methodB] ?? false ? mock.methodB(b) : super.methodB(b);
}
#GenerateMocks([ClassForTesting])
void main() {
test('Test partial mock', () {
var partialMock = PartialMockClassForTesting();
partialMock.shouldMock[partialMock.methodA] = true;
partialMock.shouldMock[partialMock.methodB] = true;
...
I want to define a constructor that takes fanction as parameter and return a value
Like this:
class app {
app({itemBuilder: itemBuilder});
int itemBuilder(int? index) {
return 1;
}
}
The question is unclear, but here is a snippet of passing the function as a parameter
class app {
final Function app;
app({this.itemBuilder: itemBuilder});
}
final obj = app(itemBuilder: (){
})
I think what you need is the static function to create and return a value.
class AppData890 {
static int itemBuilder(int index) {
return 1;
}
}
use it like this
AppData890.itemBuilder(1);
If you need it as you state the question
Tornike is ri8.
for more info about static head to
https://dart.dev/guides/language/language-tour#class-variables-and-methods
Flutter doesn't allow what you did because The default value of an optional parameter must be constant. Just try with this
class app {
app({itemBuilder});
int itemBuilder(int? index) {
return 1;
}
}
or you can also try and no need to use constructor.
class app {
static int itemBuilder(int? index) {
return index??1;
}
}
// call from outside
app.itemBuilder(5);
I am new to programming. I was not able to understand the use of call back by function pointer clearly. Please help me to understand where actually the function pointers are needed. I have given two examples. One callback using function pointer and other the normal way(Function calling a function). Forgive me if it appears silly.
#include<stdio.h>
void A()
{
printf("Hello");
}
void B(void(*ptr)())
{
ptr();
}
int main
{
void (*p)() = A;
B(p);
}
Another method
#include<stdio.h>
void A()
{
printf("Hello");
}
void B()
{
A();
}
int main
{
B();
}
What is the use of callback using function pointer when this can be achieved in a simpler way?
I have this fibonacci number generator.
struct FibonacciSeries
{
int first = 0;
int second = 1;
enum empty = false;
#property int front() const
{
return first;
}
void popFront()
{
int third = first + second;
first = second;
second = third;
}
#property FibonacciSeries save() const
{
return this;
}
}
This struct does not have the take method, so I have this error when executing this command (writeln(FibonacciSeries().take(5))).
a.d(66): Error: no property 'take' for type 'FibonacciSeries'
However, by importing range package, it has the take method. What's the mechanism behind this?
The mechanism is Uniform Function Call Syntax:
http://dlang.org/function.html#pseudo-member
To put it simply, if a.foo(b...) is not valid, the compiler tries rewriting it to foo(a, b...).
I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}