1

I added the nuget FluentAssertions 6.7.0 in a test project using .NET Framework 4.6.1. I run tests from Rider 2022.1.1.

I'm new to this nuget and I read the intro and searched for issues (none found). I come from the Should family and trying to upgrade.

I cannot build with basic assertions. Here is the initial code:

    using FluentAssertions;
    using Moq;
    using System;
    using Xunit;

    public class MyTestClass
    {
        [Fact]
        public void GetProvider_ByRemoteName_Works()
        {
            // input
            var desiredRemoteName = "Remote2";
            
            // prepare
            var context = Context.New(); // mocks and stubs
            
            // execute
            var result = context.SomeService.GetProvider(desiredRemoteName);
            
            // verify
            result.Should().NotBeNull();                      // error line
            result.Should().BeOfType<MyProviderClient>();     // error line
        }

The build errors are:

error CS0012: The type 'DataTable' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
error CS0012: The type 'DataColumn' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
...
error CS0012: The type 'DataRow' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

I don't understand why I should reference this "System.Data" assembly. That does not seem legit. If I do reference it:

MyTestClass.cs: [CS0121] The call is ambiguous between the following methods or properties: 'DataRowAssertionExtensions.Should(TDataRow)' and 'DataSetAssertionExtensions.Should(TDataSet)'


Also, removing the error lines and using line provide a valid build and test run.

Also, the IDE editor indicates:

The call is ambiguous between the following methods or properties: 'DataRowAssertionExtensions.Should(TDataRow)' and 'DataSetAssertionExtensions.Should(TDataSet)'

Also, using Xunit's assertions works:

            // verify
            Assert.NotNull(result);
            Assert.IsType<MyProviderClient>(result);

Following up on your comments, let's consider this updated code:

            // execute
            object result = context.SomeService.GetProvider(desiredRemoteName);

            // verify
            result.Should().BeAssignableTo<IMyInterface>()
               .And.BeOfType<SomeImplementation>()
               .Which
               .Configuration
               .Should()                    // error line
               .NotBeNull();

The same error occurs on the latest .Should() call.

MyTestClass.cs: [CS0121] The call is ambiguous between the following methods or properties: 'DataRowAssertionExtensions.Should(TDataRow)' and 'DataSetAssertionExtensions.Should(TDataSet)'

Is it considered "normal" with FluentAssertions to do .BeOfType<>().Which everywhere? I feel something is wrong on my side or in the way the lib works.

SandRock
  • 5,276
  • 3
  • 30
  • 49

2 Answers2

0

The IDE error you listed suggests that the compiler doesn't know which of the .Should() overloads to call. This isn't unusual for any library that relies on overload resolution.

Since it looks like you're only intending to test the return type in this context, you only "need" the ObjectAssertions overload of .Should(). As such, one way you could avoid the ambiguous invocation like this:

object result = context.SomeService.GetProvider(desiredRemoteName);
            
result.Should().BeOfType<MyProviderClient>() // Chained FA assertions are now typed as MyProviderClient
    .Which.Should().BeEquivalentTo(new { Foo = "bar" });

Observe: Demonstration of chained assertion typing

Remember that the value null does not have a runtime type, so asserting that an object has some specific runtime type implicitly asserts that it is not null. FA's .BeOfType<T>() assertion will fail with a specific message if a null reference is asserted on.

Tullo_x86
  • 2,573
  • 25
  • 27
  • The compiler is okay when the variable type is `object`. If I use correct type (come interface), the compiler still cannot build. I would like to test more than the correct type and declaring the result as `object` will not do the trick. – SandRock Jun 22 '22 at 09:01
  • In that case, you're going to need to figure out where your dependency resolution is broken. Check that you aren't mixing and matching libraries from NetFx and netcore. There's a good chance that you need to explicitly include the same dependency version in your unit test project as your main project. – Tullo_x86 Jun 22 '22 at 16:31
  • That looks fine. So I tried the `.Which` thing and though it would do. Unfortunately, the following `.Should()` invoke also generates the same build error for ambiguous call. I will check the references in my projects and try again. – SandRock Jun 23 '22 at 08:56
0

As I recall, there's a weird issue with .NET Framework 4.6.1 where the assembly reference to System.Data wasn't automatically added. For newer framework versions, it happens automatically.

Dennis Doomen
  • 8,368
  • 1
  • 32
  • 44
  • I am now referencing `System.Data`. A compiler error persists about type ambiguity (question edited). – SandRock Jun 22 '22 at 09:02