I would like to test a class GetInput
that gets keyboard input from the user. How can my test class provide simulated keyboard input to GetInput
? Here's the class to be tested.
classdef GetInput
properties
Answer
end
methods
function obj = GetInput
obj.Answer = input("Your answer? ","s");
end
end
end
And here's the test class.
classdef testGetInput < matlab.unittest.TestCase
methods (Test)
function tInput(testCase)
g = GetInput();
myInput = 'abcdef';
% I want to provide input automatically at this point
verifyEqual(testCase,g.Answer,myInput)
end
end
end
This all works, but only if I manually type in "abcdef" at the command window prompt. I want a way to automate the keyboard input.
Here's how you can do it. It's a bit roundabout. Start with an input interface class:
classdef (Abstract) InputInterface
methods
inp = getInput(inputGetter,prompt)
end
end
Create a default input class KeyboardInput that inherits from the abstract interface:
classdef KeyboardInput < InputInterface
methods
function inp = getInput(~,prompt) % 1st input arg is InputInterface obj
inp = input(prompt,"s");
end
end
end
Add a class UserQuery that uses one of these input classes:
classdef UserQuery < handle
properties
InputSource
Response
end
methods
function obj = UserQuery(inputSrc)
arguments
inputSrc (1,1) InputInterface = KeyboardInput
end
obj.InputSource = inputSrc;
end
function ask(obj,prompt)
obj.Response = obj.InputSource.getInput(prompt);
end
end
end
Now test UserQuery with a mock:
classdef tUserQuery < matlab.mock.TestCase
properties
Mock
Behavior
Asker
end
methods (Test)
function testInput(tc)
userSaid = "whatUserSaid";
when(tc.Behavior.getInput(99), ...
matlab.mock.actions.AssignOutputs(userSaid))
tc.Asker.ask(99)
tc.verifyTrue(isequal(tc.Asker.Response,userSaid))
end
end
methods (TestClassSetup)
function setupMock(tc)
[tc.Mock,tc.Behavior] = tc.createMock(?InputInterface);
tc.Asker = UserQuery(tc.Mock);
end
end
end
The mock inherits from the abstract InputInterface, so the UserQuery accepts it as an input argument. The mock behavior is set up so that when it's called with input argument 99, it outputs "whatUserSaid".
>> q = UserQuery(KeyboardInput);
>> q.ask("Your answer? ")
Your answer? yes
>> q
q =
UserQuery with properties:
InputSource: [1×1 KeyboardInput]
Response: 'yes'
>>