# How-to guides - Writing tests for streaming triggers/actions
In this segment, we will be going through how you can write tests for actions that utilize Workato's file streaming capabilities. To do this, we will be using the generic upload file to url connector example here.
# Generating your tests
You can create a separate spec file for each action or generate your tests based on your connector by using the workato generate test
command. This will generate a spec file which will include most of the necessary stubs for your to start writing tests.
# Sample RSpec contents
RSpec.describe 'actions/upload_file_to_url', :vcr do
let(:connector) { Workato::Connector::Sdk::Connector.from_file('connector.rb', settings) }
let(:settings) { Workato::Connector::Sdk::Settings.from_default_file }
before do
stub_const('Workato::Connector::Sdk::Stream::Reader::DEFAULT_FRAME_SIZE', 5.kilobytes)
end
let(:action) { connector.actions.upload_file_to_url }
describe 'execute' do
subject(:output) { action.execute(settings, input) }
let(:input) do
{
"file_name": "sample_file",
"file": {
"__stream__": true,
"chunks": {
"0": "abcd",
"4": "efgh",
"8": "ijkl",
"12": "mn"
}
},
"url": "https://www.friendly_s3_url.com/upload"
}
end
it 'given simple stream' do
it 'produces a file' do
is_expected.to include(:file_size)
expect(output.file_size).to eq(13)
is_expected.to include(:file_path)
is_expected.to include(:file_name)
end
end
end
end
# Step 1 - Define your connector instance
To begin testing, you need to use the Workato SDK Gem to create an instance of your connector.
let(:connector) { Workato::Connector::Sdk::Connector.from_file('connector.rb', settings) }
# Step 2 - Define your settings instance
Next, you need to use the Workato SDK Gem to create an instance of your settings. This is synonymous with your connection on Workato. Take note that, your connector instance previously defined also uses this settings instance.
let(:settings) { Workato::Connector::Sdk::Settings.from_default_file }
# Step 3 - Define your action
After creating the related instances, we instantiate the action
so we can reference it more easily in the rest of the tests.
let(:action) { connector.actions.upload_file_to_url }
# Step 3 - Describe your tests, define your subject and input
Here, we describe the "family" of tests we are hoping to run. In this case, we use the keyword execute
. Next, we make the subject the output which is the outcome of the execution of the action. Lastly, we declare the input
which is a simple stream.
describe 'execute' do
subject(:output) { action.execute(settings, input) }
let(:input) do
{
"file_name": "sample_file",
"file": {
# this hash simulates a file stream which is
# the output of a download file object
"__stream__": true,
"chunks": {
"0": "abcd",
"4": "efgh",
"8": "ijkl",
"12": "mn"
}
},
"url": "https://www.friendly_s3_url.com/upload"
}
end
# Step 4 - Declare your assertions for individual tests
For a test to pass or fail, there needs to be a declared comparison.
Over here, we are declaring that we "expect" the output of the execute
lambda to include keys file_size
, file_path
and file_name
. Furthermore, we expect the file_size
value to be 13.
it 'given simple stream' do
it 'produces a file' do
is_expected.to include(:file_size)
expect(output.file_size).to eq(13)
is_expected.to include(:file_path)
is_expected.to include(:file_name)
end
end
# Variations to mock streams in RSpec
Alongside mocking simple streams within your RSpec tests, you have the ability mock other variations as well.
Mock streams with each chunk explicitly
let(:input) do
{
file_name: 'sample_file',
file: {
__stream__: true,
chunks: {
0 => 'abcd',
4 => 'efgh',
8 => 'ijkl',
12 => 'mn'
}
},
url: 'https://www.friendly_s3_url.com/upload'
}
end
Mock streams by utilizing a stream implemented for a download file action/trigger in the same connector
let(:input) do
{
file_name: 'sample_file',
file: {
__stream__: true,
name: 'global_stream',
input: {
file_path: '/path/to/sample/file'
}
},
url: 'https://www.friendly_s3_url.com/upload'
}
end
Mock streams by providing the inline definition of a stream with its own authentication
TIP
Advanced mocks like these are only available in RSpec tests and not in CLI execution.
let(:input) do
{
file_name: 'sample_file',
file: {
__stream__: true,
name: 'mock_advanced_stream',
input: {
file_path: '/path/to/sample/file'
},
settings: {
# optional
# A connection settings for stream mock application
# if the mock makes authorized requests to external apps
# Also can use Workato::Connector::Sdk::Settings.from_file
domain: 'acme.egnyte.com',
api_key: 'api_key'
},
connection: {
# optional
# A connection definition for stream source applications
# if the mock makes authorized requests to external apps
# It supports the same blocks as connector's connection definition
authorization: {
type: 'api_key',
apply: lambda do |connection|
headers(api_key: connection['api_key'])
end
},
},
chunks: lambda do |input, _first_byte, last_byte, size|
chunk = get("/pubapi/v1/fs-content/#{file_path}").
headers("Range": "bytes=#{starting_byte_range}-#{ending_byte_range}").
response_format_raw
[chunk, chunk.size < requested_byte_size]
end
},
url: 'https://www.friendly_s3_url.com/upload'
}
end
Mock streams by providing a static stream
let(:input) do
{
file_name: 'sample_file',
file: {
data: '1234567890',
oef: true
},
url: 'https://www.friendly_s3_url.com/upload'
}
end
Mock streams by providing a string
let(:input) do
{
file_name: 'sample_file',
file: 'qwertyuiop[]',
url: 'https://www.friendly_s3_url.com/upload'
}
end
Last updated: 12/20/2023, 11:22:08 PM