| // 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'; |
| |
| Invocation lastInvocation; |
| |
| void main() { |
| const stub = const 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), |
| "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), |
| "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); |
| say(String text); |
| eat(String food, {bool alsoDrink}); |
| lie([bool facingDown]); |
| fly({int miles}); |
| } |
| |
| /// An example of a class that captures Invocation objects. |
| /// |
| /// Any call always returns an [Invocation]. |
| class Stub implements Interface { |
| static Invocation lastInvocation; |
| |
| const Stub(); |
| |
| @override |
| noSuchMethod(Invocation invocation) { |
| lastInvocation = invocation; |
| } |
| } |
| |
| // Copied from package:test, which doesn't expose it to users. |
| // https://github.com/dart-lang/matcher/issues/39 |
| void shouldFail(value, Matcher matcher, expected) { |
| var failed = false; |
| try { |
| expect(value, matcher); |
| } on TestFailure catch (err) { |
| failed = true; |
| |
| var _errorString = err.message; |
| |
| if (expected is String) { |
| expect(_errorString, equalsIgnoringWhitespace(expected)); |
| } else { |
| expect(_errorString.replaceAll('\n', ''), expected); |
| } |
| } |
| |
| expect(failed, isTrue, reason: 'Expected to fail.'); |
| } |
| |
| void shouldPass(value, Matcher matcher) { |
| expect(value, matcher); |
| } |