tags:

views:

120

answers:

4

Visual sutdio 2008 has the ability to automatically create unit test stubs. I have used this to create some basic unit tests, but I am confused by something:

  private class bla : BaseStoreItem
     {
     //
     }

  /// <summary>
  ///A test for StoreData
  ///</summary>
  public void StoreDataTestHelper<T>() where T : BaseStoreItem
     {
     FileStore<T> target = new FileStore<T>(); // TODO: Initialize to an appropriate value

     BaseStoreItem data = new bla();

     target.StoreData(data);
     }

  [TestMethod()]
  public void StoreDataTest()
     {
     //Assert.Inconclusive("No appropriate type parameter is found to satisfies the type constraint(s) of T. " +
     //        "Please call StoreDataTestHelper<T>() with appropriate type parameters.");

     StoreDataTestHelper<bla>();
     }

Why do I get "Error: Cannot convert type 'StorageUnitTests.FileStoreTest.bla' to 'T'" when T is type "bla"?

I know "bla" is not a good function name, but its just an example.

+4  A: 

why not that way? (It doesn't make much sence to create an instance of bla inside of StoreDataTestHelper if you have access to T)

 public void StoreDataTestHelper<T>() where T : BaseStoreItem, new()
 {
     FileStore<T> target = new FileStore<T>(); 

     T data = new T();

     target.StoreData(data);
 }
gsharp
I think it should be Activator.CreateInstance<T>() instead of new T() ..
Akash Kava
@Akash Why? Activator.CreateInstance use reflection and it's slow. It think new T() is much more elegant.
gsharp
gsharp, sorry i missed ,new() constraint in your code, in the question since ,new() was not specified
Akash Kava
I never knew about the "new()" bit. Thank you gsharp :)
Nippysaurus
A: 

Because, if T is DerivedStoreItem (inheriting BaseStoreItem), you would be violating the type of FileStore<T> by storing a BaseStoreItem.

Tormod Fjeldskår
A: 

This makes sense. By specifying T: BaseStoreItem, you have guaranteed that T will be a type the has BaseStoreItem as a base class, and NOT that it will necessarily be a BaseStoreItem. Therefore, if T is later set to be some type that derives from BaseStoreItem, your target.StoreData(data); line would be performing an illegal operation.

Although in your case you only invoke StoreDataTestHelper with T set to bla, C#'s typechecker needs to make sure that the code for StoreDataTestHelper is type-safe in general. This is one of benefits to a strongly-typed language: it catches potential typing mistakes before you make them.

smehmood
+1  A: 

when T is type "bla"

Your above condition holds true only for current case, but I can create a nother class

public class Bla2: BaseStoreItem {...

Then Bla2 <> bla ... , neither Bla2 is derived from bla, so if I try to use

StoreDataTestHelper<Bla2>(); 

This is wrong, compiler is smart enough to understand that in this condition it will not work, computer languages are not like english, they are created to work exactly same in all conditions. And they are designed so that rules of language are correct in all cases. If they differ you will have chaos finding where the error is.

Akash Kava