Olá Willian,
a grande vantagem do Builder, principalmente quando se trata de teste, vem muito da questão de melhorar a semântica e fazer o teste intereferir o menos possível na lógica de negócio.
Por exemplo, se formos fazer o mesmo código do curso usando as propriedades, ficaria assim:
NotaFiscal nota = new NotaFiscal();
nota.RazaoSocial = "Caelum";
nota.Cnpj = "123.456.789/0001-10";
IList<ItemDaNota> itens = new List<ItemDaNota>();
itens.Add(new ItemDaNota("item 1", 100.0));
itens.Add(new ItemDaNota("item 2", 200.0));
itens.Add(new ItemDaNota("item 3", 300.0));
nota.Itens = itens;
nota.Observacoes = "entregar nf pessoalmente";
nota.DataDeEmissao = DateTime.Now;
E ficaria algo similar a isto usando métodos, que foi a outra solução que você comentou. Só moveria algumas destas lógicas para a classe NotaFiscal.
No caso com o Builder, o código ficou assim:
NotaFiscal nf = new NotaFiscalBuilder().ParaEmpresa("Caelum").ComCnpj("123.456.789/0001-10").ComItem(new Item("item 1", 100.0))
.ComItem(new Item("item 2", 200.0)).ComItem(new Item("item 3", 300.0)).ComObservacoes("entregar nf pessoalmente")
.NaDataAtual().Constroi();
Semanticamente, conforme você lê o código desta versão com o Builder parece que você está lendo um texto normal e não código de programação. Parece que é dito "Me faz uma Nota fiscal para a empresa Caelum com Cpnj 123.456.789/0001-10 etc". Principalmente para pessoas que estão entrando/começando no projeto acaba sendo mais fácil de ler um código semântico do que um monte de chamadas de propriedades.
Além disso, quando falamos de testes é comum termos diferentes cases/métodos de teste, cada um testando um cenário específico. E cada um dos testes teria que criar uma Nota Fiscal e preencher as propriedades com valores fazem sentido. Seria basicamente repetir aquele primeiro bloco lá de cima várias vezes, mudando as vezes o valor de 1 parâmetro de um cenário para o outro. Uma opção seria criar um construtor ou método na classe NotaFiscal que insere alguns valores default e em cada cenário você apenas troca os parâmetros que fazem sentido mexer para aquele cenário. Mas ai estaríamos interferindo na regra de negócio para facilitar a vida nas classes de teste. Com o Builder, no próprio construtor do NotaFiscalBuilder podemos já definir estes valores default que servem para os testes. Por exemplo, se este construtor já assume valores default e precisarmos fazer um teste em que o cenário precisa apenas da informação RazaoSocial, poderíamos criar o objeto assim:
NotaFiscal nfCaelum = new NotaFiscalBuilder() // aqui já coloca um valor default em RazaoSocial, Cnpj, Itens, Observacoes, etc
.ParaEmpresa("Caelum") //troca apenas o específico para o cenário teste
.Constroi();
A linha continua parecendo um texto semanticamente falando e não alteramos a regra de negócio para ser usada apenas no teste, mexemos apenas nas classes Builders destinadas para os testes..