小编Che*_*hen的帖子

在单元测试中模拟HTTPResponse

我正在尝试为一些遗留代码创建单元测试.我必须测试的一个类叫做FileDownloader,它只有以下一个方法:

public void Transmit(string fileName, HttpResponse response, DownloadFileType fileType, byte[] content)
{
    response.Clear();
    response.ClearHeaders();
    response.ContentType = "application/xls";
    response.AddHeader("content-disposition", "attachment; filename=" + HttpContext.Current.Server.UrlEncode(fileName));
    response.BinaryWrite(content);
    response.End();
    response.Flush();
}
Run Code Online (Sandbox Code Playgroud)

我不允许重构这个代码(这本来是理想的!).

为了测试这个,我决定根据下面的文章创建一个假的HttpContext

点击这个

有了这个,我可以在测试执行期间获得假的HttpContext,但是伪造HttpResponse存在问题.

以下是我的测试结果:

[SetUp]
public void SetUp()
{
    mocks = new MockRepository();            
    FakeHttpContext.CreateFakeHttpContext();
}

[Test]
public void ShouldTransmitHttpResponseInTheSpecifiedFormat()
{
    FileDownloader downloader = new FileDownloader();
    string path = "..\\..\\Fakes\\DummyDownloadReportsTemplate.xls";
    byte[] bytes = ReadByteArrayFromFile(path);
    downloader.Transmit("test.xls", new HttpResponse(new StringWriter()), DownloadFileType.Excel, bytes);
}
Run Code Online (Sandbox Code Playgroud)

我正在将自定义创建的HTTPResponse对象传递给该方法.当它命中"response.BinaryWrite(content)"行时抛出以下异常:

System.Web.HttpException:使用自定义TextWriter时,OutputStream不可用.

我不确定我究竟应该在这里断言...因此在测试中没有断言.这是测试这种方法的正确方法......任何想法.请指教 ?

谢谢

c# testing nunit mocking httpresponse

6
推荐指数
2
解决办法
7787
查看次数

可以在IEnumerator.GetEnumerator()中返回IEnumerator <T> .GetEnumerator()吗?

基本上假设你有一些收藏:

public class FurCollection : IEnumerable<FurStrand>
{
   public IEnumerator<FurStrand> GetEnumerator()
   {
      foreach(var strand in this.Strands)
      {
         yield return strand;
      }
   }

   IEnumerator IEnumerable.GetEnumerator()
   {
      return this.GetEnumerator();
   }
}
Run Code Online (Sandbox Code Playgroud)

这可以接受吗?或者这是容易出错还是不好的做法?我几乎总是使用IEnumerator<T>但我仍然希望非通用版本稳定并正确实现.

.net c# ienumerable

6
推荐指数
2
解决办法
1026
查看次数

在存储库<T>中返回Queryable <T>或List <T>

目前我正在使用sqlite构建一个Windows应用程序.在数据库中有一个表说User,在我的代码中有一个Repository<User>和一个UserManager.我认为这是一个非常常见的设计.在存储库中有一个List方法:

//Repository<User> class
public List<User> List(where, orderby, topN parameters and etc)
{
    //query and return
}
Run Code Online (Sandbox Code Playgroud)

这带来了一个问题,如果我想做一些复杂的事情UserManager.cs:

//UserManager.cs
public List<User> ListUsersWithBankAccounts()
{
    var userRep = new UserRepository();
    var bankRep = new BankAccountRepository();
    var result = //do something complex, say "I want the users live in NY 
                 //and have at least two bank accounts in the system
}
Run Code Online (Sandbox Code Playgroud)

你可以看到,返回List<User>会带来性能问题,因为查询的执行时间早于预期.现在我需要将其更改为IQueryable<T>:

//Repository<User> class
public TableQuery<User> List(where, orderby, topN parameters …
Run Code Online (Sandbox Code Playgroud)

.net c# architecture data-access-layer business-layer

6
推荐指数
1
解决办法
3696
查看次数

不区分大小写的字符串比较奇怪的行为

这种情况发生在C#和Java中,所以我认为这不是一个bug,只是想知道为什么.

var s = "";
var lower = s.ToLower();
var upper = s.ToUpper();

if (!lower.Equals(upper, StringComparison.OrdinalIgnoreCase))
{
    //How can this happen?
}
Run Code Online (Sandbox Code Playgroud)

根据这个页面,""的小写是"",与IgnoreCase选项相比,它们应该相等.为什么他们不平等?

.net c# java unicode

6
推荐指数
1
解决办法
128
查看次数

扩展方法和编译时检查

也许有点棘手,但我想知道为什么.在System.Linq.Enumerable.csSystem.Core.dll,我们有:

public static int Count<TSource>(this IEnumerable<TSource> source);
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我正在做一些邪恶的事:

namespace Test
{
   public static class Extensions
   {
     public static int Count<TSource>(this IEnumerable<TSource> source)
     {
        return -1; //evil code
     }
   }

   //commented temporarily
   //public static class CommentedExtensions
   //{
   //  public static int Count<TSource>(this IEnumerable<TSource> source)
   //  {
   //     return -2; //another evil code
   //  }
   //}

   public static void Main(string[] args)
   {
     Console.WriteLine(Enumerable.Range(0,10).Count());   // -1, evil code works
     Console.Read();
   }
}
Run Code Online (Sandbox Code Playgroud)

如果我取消注释CommentedExtensions,我将收到一个编译错误,说"这个调用是不明确的blabla",如预期的那样.但为什么我第一次没有得到这个错误?这也很暧昧!

编辑经过另一次测试后,我发现如果扩展方法位于不同的命名空间中,我将不会遇到编译错误,即使它们完全相同.为什么允许这样做?它在c#中引入了模糊的方法调用.

EDIT2我知道其实两个 …

.net c# linq extension-methods

5
推荐指数
1
解决办法
911
查看次数

部署Windows 8应用程序

当我在visual studio 2012 RC中编译我的应用程序时,我可以看到bin\项目源文件夹中按预期生成的文件夹,其中有一个foo.exe,看起来像应用程序的条目.当我开始调试应用程序时,它的图标被放在开始屏幕上,我可以找到创建的新文件夹

C:\用户\人\应用程序数据\本地\包\ xxxxx_xxxxxx

但是我在这个文件夹中找不到foo.exe,即使我搜索了整个磁盘.似乎win8应用程序具有与旧Windows程序不同的安装/部署机制.我的问题是:

(1)部署/安装win8应用程序的方式/位置?

(2)我想\AppData\Local\Packages\xxxxx_xxxxxx\LocalState用作本地数据文件夹(ApplicationData.Current.LocalFolder在代码中等于),但是当右键单击开始屏幕图标并按"卸载"时,整个文件夹被删除,没有任何警告.有没有更好的地方存储本地数据?或者我需要SQLite?例如,我的应用程序写入所有崩溃消息error.txt,显然我不能在这种情况下使用sqlite,如果我放入error.txtLocalState文件夹,用户可能已经卸载了应用程序,然后我去找他看看是什么error.txt.另一种情况是:用户想要卸载应用程序,但保留其本地数据(文件).显然ApplicationData.Current.LocalFolder不是一个好选择.

c# local-storage windows-8

5
推荐指数
1
解决办法
3148
查看次数

异步/等待任务和WaitHandle

假设我有10N个项目(我需要通过http协议来获取它们),在代码N中开始启动任务以获取数据,每个任务依次获取10个项目。我把这些东西放在一个盒子里ConcurrentQueue<Item>。之后,将以不安全线程的方法一一处理这些项目。

async Task<Item> GetItemAsync()
{
    //fetch one item from the internet
}

async Task DoWork()
{
    var tasks = new List<Task>();
    var items = new ConcurrentQueue<Item>();
    var handles = new List<ManualResetEvent>();

    for i 1 -> N
    {
        var handle = new ManualResetEvent(false);
        handles.Add(handle);

        tasks.Add(Task.Factory.StartNew(async delegate
        {
            for j 1 -> 10
            {
                var item = await GetItemAsync();
                items.Enqueue(item);
            }
            handle.Set();
        });
    }

    //begin to process the items when any handle is set
    WaitHandle.WaitAny(handles);

    while(true)
    {
         if (all handles …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous task waithandle async-await

5
推荐指数
1
解决办法
1万
查看次数

c#中的异步属性

在我的Windows 8应用程序中有一个全局类,其中有一些静态属性,如:

public class EnvironmentEx
{
     public static User CurrentUser { get; set; }
     //and some other static properties

     //notice this one
     public static StorageFolder AppRootFolder
     {
         get
         {
              return KnownFolders.DocumentsLibrary                    
               .CreateFolderAsync("theApp", CreationCollisionOption.OpenIfExists)
               .GetResults();
         }
     }
}
Run Code Online (Sandbox Code Playgroud)

您可以看到我想在项目的其他位置使用应用程序根文件夹,因此我将其设置为静态属性.在getter中,我需要确保根文件夹存在,否则创建它.但这CreateFolderAsync是一个异步方法,这里我需要一个同步操作.我试过了,GetResults()但它抛出一个InvalidOperationException.什么是正确的实施?(package.appmanifest已正确配置,实际创建了该文件夹.)

.net c# asynchronous async-await

5
推荐指数
2
解决办法
2万
查看次数

JSON.NET属性的替代解决方案

当前在我的模型类中,我有一些JSON.NET属性,例如

public class MyModel
{
     [JsonProperty("_anothername")]
     [JsonConverter(typeof(MyCustomConverter))]
     public string Name { get; set; }     
}
Run Code Online (Sandbox Code Playgroud)

是否有其他解决方案不会“污染”我的模型类?合同解析器可能有效,但是它太重了。我想要这样的东西:

var contract = new JsonContract<MyModel>();
contract.Property(m => m.Name)
        .HasAlias("_anothername")
        .HasConverter<MyCustomConverter>();
JsonConvert.SerializeObject(myModelInstance, contract);
Run Code Online (Sandbox Code Playgroud)

理想情况下,模型类对JSON.NET一无所知,并且该项目不应具有JSON.NET参考。

编辑:也许其他一些JSON库可以工作,但是我不想涉及另一个库,因为JSON.NET在该项目中被广泛使用。

更新:似乎合同解析器是执行此操作的标准方法,我发现此库接近我的期望。稍后,我将尝试编写自己的实现。

.net c# json json.net

5
推荐指数
0
解决办法
529
查看次数

字符串插值中可避免的装箱

使用字符串插值使我的字符串格式看起来更加清晰,但是.ToString()如果我的数据是值类型,我必须添加调用。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var person = new Person { Name = "Tom", Age = 10 };
var displayText = $"Name: {person.Name}, Age: {person.Age.ToString()}";
Run Code Online (Sandbox Code Playgroud)

.ToString()使得格式更长更难看。我试图摆脱它,但它string.Format是一个内置的静态方法,我无法注入它。你对此有什么想法吗?而且既然字符串插值是 的语法糖string.Format,为什么.ToString()在生成语法糖背后的代码时不添加调用呢?我认为这是可行的。

.net c# string string-interpolation

5
推荐指数
1
解决办法
581
查看次数