views:

58

answers:

3

I have a web page that shows different messages according to different conditions. I want to unit test this so I configured my project to use MVVM and I'm testing my ViewModel.

My ViewModel now format different messages. How can I test this? I don't want to reproduce all strings, it seems dirty...

Now I'm doing this:

void test() 
{
    string message = _viewModel.DoWork();
    Assert.AreEqual(message, Resource.MyResourceText);
}

But this is a simple case. Now I have dynamic strings containing system date and other variables.

How can I test this in an elegant way? Thanks!

+2  A: 

If your concern is just reproducing strings in your test fixtures, put them all in an enum or class.

public static class StatusMessage 
{
    public static readonly string SavedSuccessfully
        = "Item was successfully saved.";
    public static readonly string DuplicateRecord
        = "This record is a duplicate.";
    public static readonly string SubscriptionExpired
        = "Your subscription has expired; please renew now.");
}

Now your viewmodel can perform its logic and return one of the StatusMessages:

public class SomeViewModel
{
    ...

    public string Status
    {
        get { return StatusMessage.SavedSuccessfully; }
    }

    ...
}

In your test:

Assert.AreEqual(StatusMessage.SavedSuccessfully, viewmodel.Status);
Jay
it's great, but I'm already using resources file (see my updated question). The problem is that I'm using dynamic strings...
Ricibald
@Ricibald -- could be a bit dicey in a unit test, but you could use regular expressions or `string.Contains()` to validate the message.
Jay
+1  A: 

I will go with what you are currently doing or may be what @Jay has suggested.

But, I really don't understand when you say,

Now I have dynamic strings containing system date and other variables.

The expected string always HAS to be hardcoded in order to unit test it. You should never ever use any calculation in unit test. You should set a scenario (date, any other vars) and then you know what your expected string will be. You will then hardcode it. If you want to unit test the same method for different strings you can use TestCase attribute in nunit or RowTest attribute in MBUnit.

P.K
ok, but in this way it seems that I'm repeating the underlying implementation. I want to test my class as a black box
Ricibald
You will be repeating the implementation if you have the logic in your code and not by having expected string. When I say that you should set a scenario, it means you just set certain vars.
P.K
A: 
Ricibald