blob: 9b139abdb5b84c352a554ff6161241ada03a10c0 [file] [log] [blame]
// Copyright 2016 Dart Mockito authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'package:mockito/src/invocation_matcher.dart';
import 'package:test/test.dart';
void main() {
const stub = Stub();
group('$isInvocation', () {
test('positional arguments', () {
stub.say('Hello');
var call1 = Stub.lastInvocation;
stub.say('Hello');
var call2 = Stub.lastInvocation;
stub.say('Guten Tag');
var call3 = Stub.lastInvocation;
shouldPass(call1, isInvocation(call2));
shouldFail(
call1,
isInvocation(call3),
"Expected: say('Guten Tag') "
"Actual: <Instance of '${call3.runtimeType}'> "
"Which: Does not match say('Hello')",
);
});
test('named arguments', () {
stub.eat('Chicken', alsoDrink: true);
var call1 = Stub.lastInvocation;
stub.eat('Chicken', alsoDrink: true);
var call2 = Stub.lastInvocation;
stub.eat('Chicken', alsoDrink: false);
var call3 = Stub.lastInvocation;
shouldPass(call1, isInvocation(call2));
shouldFail(
call1,
isInvocation(call3),
"Expected: eat('Chicken', 'alsoDrink: false') "
"Actual: <Instance of '${call3.runtimeType}'> "
"Which: Does not match eat('Chicken', 'alsoDrink: true')",
);
});
test('optional arguments', () {
stub.lie(true);
var call1 = Stub.lastInvocation;
stub.lie(true);
var call2 = Stub.lastInvocation;
stub.lie(false);
var call3 = Stub.lastInvocation;
shouldPass(call1, isInvocation(call2));
shouldFail(
call1,
isInvocation(call3),
'Expected: lie(<false>) '
"Actual: <Instance of '${call3.runtimeType}'> "
'Which: Does not match lie(<true>)',
);
});
test('getter', () {
stub.value;
var call1 = Stub.lastInvocation;
stub.value;
var call2 = Stub.lastInvocation;
stub.value = true;
var call3 = Stub.lastInvocation;
shouldPass(call1, isInvocation(call2));
shouldFail(
call1,
isInvocation(call3),
// RegExp needed because of https://github.com/dart-lang/sdk/issues/33565
RegExp('Expected: set value=? <true> '
"Actual: <Instance of '${call3.runtimeType}'> "
'Which: Does not match get value'),
);
});
test('setter', () {
stub.value = true;
var call1 = Stub.lastInvocation;
stub.value = true;
var call2 = Stub.lastInvocation;
stub.value = false;
var call3 = Stub.lastInvocation;
shouldPass(call1, isInvocation(call2));
shouldFail(
call1,
isInvocation(call3),
// RegExp needed because of https://github.com/dart-lang/sdk/issues/33565
RegExp('Expected: set value=? <false> '
"Actual: <Instance of '${call3.runtimeType}'> "
'Which: Does not match set value=? <true>'),
);
});
});
group('$invokes', () {
test('positional arguments', () {
stub.say('Hello');
var call = Stub.lastInvocation;
shouldPass(call, invokes(#say, positionalArguments: ['Hello']));
shouldPass(call, invokes(#say, positionalArguments: [anything]));
shouldFail(
call,
invokes(#say, positionalArguments: [isNull]),
'Expected: say(null) '
"Actual: <Instance of '${call.runtimeType}'> "
"Which: Does not match say('Hello')",
);
});
test('named arguments', () {
stub.fly(miles: 10);
var call = Stub.lastInvocation;
shouldPass(call, invokes(#fly, namedArguments: {#miles: 10}));
shouldPass(call, invokes(#fly, namedArguments: {#miles: greaterThan(5)}));
shouldFail(
call,
invokes(#fly, namedArguments: {#miles: 11}),
"Expected: fly('miles: 11') "
"Actual: <Instance of '${call.runtimeType}'> "
"Which: Does not match fly('miles: 10')",
);
});
});
}
abstract class Interface {
bool? get value;
set value(value);
void say(String text);
void eat(String food, {bool? alsoDrink});
void lie([bool? facingDown]);
void fly({int? miles});
}
/// An example of a class that captures Invocation objects.
///
/// Any call always returns an [Invocation].
class Stub implements Interface {
static late Invocation lastInvocation;
const Stub();
@override
void noSuchMethod(Invocation invocation) {
lastInvocation = invocation;
}
}
// Inspired by shouldFail() from package:test, which doesn't expose it to users.
void shouldFail(value, Matcher matcher, expected) {
const reason = 'Expected to fail.';
try {
expect(value, matcher);
fail(reason);
} on TestFailure catch (e) {
final matcher = expected is String
? equalsIgnoringWhitespace(expected)
: expected is RegExp
? contains(expected)
: expected;
expect(collapseWhitespace(e.message!), matcher, reason: reason);
}
}
void shouldPass(value, Matcher matcher) {
expect(value, matcher);
}