AlignedDev
AlignedDev

Reputation: 8232

Assert.ThrowsExceptionAsync isn't working

Question:

I haven't found much about MSTest V2 for examples or documentation. What is the correct way to use Assert.ThrowsExceptionAsync?

public void GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException()
{
    var playlistId = Guid.NewGuid().ToString();
    var manager = PlaylistTargetsFakeFactory.GetPlaylistTargetFusionManager();
    Assert.ThrowsException<PlaylistNotFoundException>(async () =>
    {
       await manager.GetPlaylistByIdAsync(playlistId);
    });
}

this also fails the test:

Assert.ThrowsException<PlaylistNotFoundException>(() =>
{
    return manager.GetPlaylistByIdAsync(playlistId);
});

Message: Assert.ThrowsException failed. No exception thrown. PlaylistNotFoundException exception was expected.

This is failing for me, even though I've debugged it and the exception is definitely thrown.

Since this is still an RC, it's possible there is a bug. I've had this in 2 tests I'm trying to convert so I can use VS 2017.

Update: This passes.

[TestMethod]
public async Task GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException()
{
    var playlistId = Guid.NewGuid().ToString();
    var manager = PlaylistTargetsFakeFactory.GetPlaylistTargetFusionManager();
    //Assert.ThrowsException<PlaylistNotFoundException>(() =>
    //{

    try
    {
        await manager.GetPlaylistByIdAsync(playlistId);
        Assert.Fail();
    }
    catch (PlaylistNotFoundException)
    {
        Assert.IsTrue(true);
    }

    //});
}

Update 2: After Stephen Cleary's answer, I made this change. Thanks for pointing out my mis-use. I had changed it awhile back because I get "Message: Test method .Test.Models.Helpers.PlaylistTargetFusionManagerTests.GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException threw exception: System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task1<!!0> Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func1<System.Threading.Tasks.Task>)'." when I run the test.

[TestMethod]
[TestCategory(TestCategories.CSharp)]
[TestCategory(TestCategories.PlaylistTargets)]
public async Task GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException()
{
    var playlistId = Guid.NewGuid().ToString();
    var manager = PlaylistTargetsFakeFactory.GetPlaylistTargetFusionManager();
    await Assert.ThrowsExceptionAsync<PlaylistNotFoundException>(() => manager.GetPlaylistByIdAsync(playlistId));
}

I have 2 packages in my packages.json

 <package id="MSTest.TestAdapter" version="1.1.9-rc2" targetFramework="net451" />
 <package id="MSTest.TestFramework" version="1.0.8-rc2" targetFramework="net451" />

Upvotes: 19

Views: 13061

Answers (4)

Eric Wild
Eric Wild

Reputation: 661

Rather than making your tests async and using await use this: Assert.ThrowsExceptionAsync<PlaylistNotFoundException>(() => manager.GetPlaylistByIdAsync(playlistId)).Wait(); The wait is helpful for testing async methods

Upvotes: 0

Miguel Domingues
Miguel Domingues

Reputation: 450

Because your method is async you can try something like this, that also allows you to test the values of the raised exception:

public void GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException()
{
    var playlistId = Guid.NewGuid().ToString();
    var manager = PlaylistTargetsFakeFactory.GetPlaylistTargetFusionManager();

    var ex = Assert.ThrowsExceptionAsync<PlaylistNotFoundException>(
            async () =>
            {
                await manager.GetPlaylistByIdAsync(playlistId);
            }).Result;

    Assert.IsTrue(ex.ErrorCode == ...);
}

Upvotes: 2

AlignedDev
AlignedDev

Reputation: 8232

After all that I went through in my question, I created a simple new project, which was .Net 4.5.2 and that worked. After I realized the .Net version difference, I changed my project and the test passed. I realize that we need to upgrade, since 4.5.1 is no longer supported by Microsoft and will start working on that as soon as I can. I guess this would have made a better blog post than an SO question.

The main fix is to change the packages.json to change targetFramework="net451" to targetFramework="net452".

<package id="MSTest.TestAdapter" version="1.1.9-rc2" targetFramework="net452" />
<package id="MSTest.TestFramework" version="1.0.8-rc2" targetFramework="net452" />

Upvotes: 0

Stephen Cleary
Stephen Cleary

Reputation: 456322

What is the correct way to use Assert.ThrowsExceptionAsync?

You're not calling ThrowsExceptionAsync. You're calling ThrowsException. The proper way to call ThrowsExceptionAsync is to await its result.

This should work:

public async Task GetPlaylistByIdAsync_NonExistingPlaylist_ThrowsPlaylistNotFoundException()
{
  var playlistId = Guid.NewGuid().ToString();
  var manager = PlaylistTargetsFakeFactory.GetPlaylistTargetFusionManager();
  await Assert.ThrowsExceptionAsync<PlaylistNotFoundException>(async () =>
  {
     await manager.GetPlaylistByIdAsync(playlistId);
  });
}

or, more simply:

  await Assert.ThrowsExceptionAsync<PlaylistNotFoundException>(() =>
     manager.GetPlaylistByIdAsync(playlistId));

Upvotes: 37

Related Questions