DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • 7 Awesome Libraries for Java Unit and Integration Testing
  • Maven Plugin Testing - in a Modern Way - Part I
  • Unit Testing and Integration Testing in Practice
  • Mocking and Its Importance in Integration and E2E Testing

Trending

  • Designing a Java Connector for Software Integrations
  • Strategies for Securing E-Commerce Applications
  • When Airflow Tasks Get Stuck in Queued: A Real-World Debugging Story
  • Designing AI Multi-Agent Systems in Java
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Integration Testing FTP Connections in .NET

Integration Testing FTP Connections in .NET

By 
Douglas Rathbone user avatar
Douglas Rathbone
·
Sep. 27, 12 · Interview
Likes (0)
Comment
Save
Tweet
Share
6.3K Views

Join the DZone community and get the full member experience.

Join For Free

when writing testable code, your first port of call is often to abstract any dependencies and make them easy to mock. this is the same for any of your codebase that talks to ftp servers. testing the way your code behaves under real world conditions makes integration tests important regardless of abstraction, though. here’s a simple trick to test ftp code in the wild.

image a recent project of mine has involved writing code that talks to ftp servers with the goal of adding additional continuous integration automation to a project. although all of my main methods are easily abstracted and injectable, my project still needs to actually talk to ftp servers at the end of the day, and i need to test that these very methods do the right thing when they are met with different conditions; be they bad credentials, lack of read/write permissions etc.

the challenge

integration tests can be brittle at the best of times, so ensuring that they are repeatable and can be setup and torn down can often be almost as much of a challenge as writing your actual code itself.

an ftp server is usually a static service that is installed on a server. you might think that running one and ensuring it stays up and doesn’t get hacked just so that all your integration tests work is a necessary evil, but there is an easier way.

run local. run often.

i was running an ftp server on my build server just so that it was “always around” for my tests until i stumbled across an interesting project over on github to do just this .

the approach i'm about to show you doesn’t need you to go to the effort of running a dedicated server at all. all you need to do is add a single executable to your unit test project and wrap your unit test in a using statement.

the ftp server executable is a single file ftp server called ftpdmin which offers a read/write ftp server that can be fired up from the command line with a minimum feature set and only a few command line parameters to make it all tick.

by implementing idisposable the helper class that wraps around this command line exe allows you to take advantage of the using() pattern to take care of your executable’s lifetime and have it die when your code is done testing.

steps to make it happen

download ftpdmin from here .

add the exe to the root of your test project (you can put this anywhere, but you’ll have to update the helper class below).

now add the exe to your project (i.e “view all items” in your test project’s solution explorer, and add the exe).

set the exe to “copy always” in it’s solution properties.

image

add the following code to a helper class in your test project:

public class ftptestserver: idisposable
{
    private readonly process ftpprocess;

    public ftptestserver(string rootdirectory, int port = 21, bool allowuploads = true)
    {
        var psinfo = new processstartinfo
            {
                filename = appdomain.currentdomain.basedirectory + "\\ftpdmin.exe",
                arguments = string.format("-p {0} -ha 127.0.0.1 \"{1}\" {2}", port, rootdirectory, allowuploads ? string.empty : "-g"),
                windowstyle = processwindowstyle.hidden
            };
        ftpprocess = process.start(psinfo);
    }

    public void dispose()
    {
        if (ftpprocess.hasexited) return;
        ftpprocess.kill();
        ftpprocess.waitforexit();
    }
}

now you can enjoy being able to write really clean integration testing code that starts and ftp server every time you run your tests and then tear it down when your test is done.

an example integration test showing connecting to “127.0.0.1”:

[testmethod]
public void ftpcode_upload_canconnect()
{
    try
    {
        // fire up a new ftp server instance
        using (new ftptestserver(rootdirectory: "./"))
        {
            // code that talks to an ftp server on 127.0.0.1
        }
    }
    catch (webexception e)
    {
        assert.fail("failed to connect to our ftp server");
    }
}

how awesome is that?

the power of using ftpdmin is that it can be told to deny write permissions to simulate bad user permissions as well:

[testmethod]
public void ftpcode_upload_throwswebexception()
{
    try
    {
        // fire up a new ftp server instance
        using (new ftptestserver(rootdirectory: "./", allowuploads: false))
        {
            // code that talks to an ftp server on 127.0.0.1
        }
    }
    catch (webexception e)
    {
        assert.fail("our code failed to upload a file because of invalid permissions");
    }
}

all in all, the above has been a complete lifesaver when it comes to making my integration test projects portable – if a new developer joins my project, they instantly get access to my ftp test harness just by pulling down my project’s source code.

Integration unit test Integration testing File Transfer Protocol

Published at DZone with permission of Douglas Rathbone, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • 7 Awesome Libraries for Java Unit and Integration Testing
  • Maven Plugin Testing - in a Modern Way - Part I
  • Unit Testing and Integration Testing in Practice
  • Mocking and Its Importance in Integration and E2E Testing

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!