A word of caution when learning about Unit Tests. Don't over-test!
IValueConverter is a good place to start with tests, and I believe you did a good job. In your comment to Nate you mentioned that you added a null test. This to me is a small form of over-testing. I'm going to assume you are using/learning about MVVM with WPF since it is most common to use that class in WPF. That particular class that you are writing about is going to bind to a boolean (not a nullable boolean) booleans initialize to false by default. So it would be a compilation error that would show the case where null can happen. That being said I would possibly remove the null check.
Now for your test.
Assert.That(btvConverter.Convert(true, typeof(Visibility), null, "en-us").Equals(Visibility.Visible));
Assert.That(btvConverter.Convert(false, typeof(Visibility), null, "en-us").Equals(Visibility.Collapsed));
when you pass in a parameter to a function, a 3rd party looking at your code will assume that need said parameter. I'm speaking directly to
"en-us". Does the culture string affect your visibility? If it was set to some other culture would I get different results? Your tests don't answer that. If that parameter is not used then pass in null.
Another thing is about your Assert. You are using the the boolean overload for
Assert.That(...). When that test fails it will tell you
"Expected true but what false". Not very helpful IMO. It's not helpful because without clicking on the Stacktrace in the TestExplorer (which isn't always available) you don't know which of those 2 asserts failed. There are a few ways to make your tests give you more explicit error messages that tell you what you want to know. One is that you can use a string after your test that gets shown when your test fails.
Assert.That(btvConverter.Convert(true, typeof(Visibility), null, "en-us").Equals(Visibility.Visible), "The converter did not return Visible when it should have");
Assert.That(btvConverter.Convert(false, typeof(Visibility), null, "en-us").Equals(Visibility.Collapsed), "The converter did not return Collapsed");
Another option is to use the
IResolveConstraints overload with NUnit. They help a little bit as well.
Assert.That(btvConverter.Convert(true, typeof(Visibility), null, "en-us"), Is.EqualTo(Visibility.Visible));
Assert.That(btvConverter.Convert(false, typeof(Visibility), null, "en-us"), Is.EqualTo(Visibility.Collapsed));
That will at show
"Expected <Visibility.Visible>, but found <Visibility.Collapsed"
that helps some too, and you don't have to add a string always.
And the last option (the one I prefer) is to use FluentAssertions. It's a personal preference, but what i like is that sometimes the TestFrame work of choice doesn't work and you end up having to switch. Using FluentAssertions you would only have to change the attributes for your test methods and test classes. Plus I like the way it reads:
public void Test()
IValueConverter converter = new BooleanToVisibilityConverter();
converter.Convert(true, null, null, null).Should().Be(Visibility.Visible);
converter.Convert(false, null, null, null).Should().Be(Visibility.Hidden);
In the fail for the second Assertion it says
Expected object to be Hidden, but found Collapsed.
Now granted this last part is personal preference. Find your niche and stay consistent.
So based on your mention of using WinRT and the mention of compilation errors when passing in a null for a string parameter leads me to believe that your best bet is to either use string.Empty or my preference is to see a field with a meaning behind its name:
unusedLanguage or something to that effect. Then when you use it in your test it reads clearly
btvConverter.Convert(true, null, null, unusedLanguage). Granted it is a little bit of a workaround and looks weird, but at least it states its intentions clearly.
and now that I've typed out btvConverter a few times it is annoying me. using the first letters of the converters name is silly. your test is specifically for a Boolean to visibility converter. converter is is clear enough of a name in the context.